[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-5117":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":45,"readmeContent":46,"aiSummary":47,"trendingCount":16,"starSnapshotCount":16,"syncStatus":19,"lastSyncTime":48,"discoverSource":49},5117,"immudb","codenotary\u002Fimmudb","codenotary","immudb - immutable database based on zero trust, SQL\u002FKey-Value\u002FDocument model, tamperproof, data change history","https:\u002F\u002Fimmudb.io",null,"Go",8982,368,76,70,0,6,24,2,38.7,"Other",false,"master",true,[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"auditable","compliance","cryptographic","database","gdpr","go","immutable","immutable-database","key-value","merkle-tree","pci-dss","performance","sql","tamper-evident","tamperproof","timetravel","verification","verify","zero-trust","2026-06-12 02:01:08","\u003C!--\n---\n\ntitle: \"immudb\"\n\ncustom_edit_url: https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Fedit\u002Fmaster\u002FREADME.md\n---\n\n-->\n\n# immudb \u003Cimg align=\"right\" src=\"img\u002FBlack%20logo%20-%20no%20background.png\" height=\"47px\" \u002F>\n\n\n[![Documentation](https:\u002F\u002Fimg.shields.io\u002Fwebsite?label=Docs&url=https%3A%2F%2Fdocs.immudb.io%2F)](https:\u002F\u002Fdocs.immudb.io\u002F)\n[![Build Status](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Factions\u002Fworkflows\u002Fpush.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Factions\u002Fworkflows\u002Fpush.yml)\n[![Go Report Card](https:\u002F\u002Fgoreportcard.com\u002Fbadge\u002Fgithub.com\u002Fcodenotary\u002Fimmudb)](https:\u002F\u002Fgoreportcard.com\u002Freport\u002Fgithub.com\u002Fcodenotary\u002Fimmudb)\n[![View SBOM](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fsbom.sh-viewSBOM-blue?link=https%3A%2F%2Fsbom.sh%2F37cbffcf-1bd3-4daf-86b7-77deb71575b7)](https:\u002F\u002Fsbom.sh\u002F37cbffcf-1bd3-4daf-86b7-77deb71575b7)\n[![Homebrew](https:\u002F\u002Fimg.shields.io\u002Fhomebrew\u002Fv\u002Fimmudb)](https:\u002F\u002Fformulae.brew.sh\u002Fformula\u002Fimmudb)\n\n[![Discord](https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F831257098368319569)](https:\u002F\u002Fdiscord.gg\u002FEWeCbkjZVu)\n[![Immudb Careers](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fcareers-We%20are%20hiring!-blue?style=flat)](https:\u002F\u002Fwww.codenotary.com\u002Fjob)\n[![Artifact Hub](https:\u002F\u002Fimg.shields.io\u002Fendpoint?url=https:\u002F\u002Fartifacthub.io\u002Fbadge\u002Frepository\u002Fcodenotary)](https:\u002F\u002Fartifacthub.io\u002Fpackages\u002Fsearch?repo=codenotary)\n\nDon't forget to ⭐ this repo if you like immudb!\n\n[:tada: 157M pulls from docker hub!](https:\u002F\u002Fhub.docker.com\u002Fr\u002Fcodenotary)\n\n---\n\nDetailed documentation can be found at https:\u002F\u002Fdocs.immudb.io\u002F\n\n---\n\n\u003Cimg align=\"right\" src=\"img\u002Fimmudb-mascot-small.png\" width=\"256px\"\u002F>\n\nimmudb is a database with built-in cryptographic proof and verification. It tracks changes in sensitive data and the integrity of the history will be protected by the clients, without the need to trust the database. It can operate as a key-value store, as a document model database, and\u002For as relational database (SQL).\n\nTraditional database transactions and logs are mutable, and therefore there is no way to know for sure if your data has been compromised. immudb is immutable. You can add new versions of existing records, but never change or delete records. This lets you store critical data without fear of it being tampered.\n\nData stored in immudb is cryptographically coherent and verifiable. Unlike blockchains, immudb can handle millions of transactions per second, and can be used both as a lightweight service or embedded in your application as a library. immudb runs everywhere, on an IoT device, your notebook, a server, on-premise or in the cloud.\n\n\nWhen used as a relational data database, it supports both transactions and blobs, so there are no limits to the use cases. Developers and organizations use immudb to secure and tamper-evident log data, sensor data, sensitive data, transactions, software build recipes, rule-base data, artifacts and even video streams. [Examples of organizations using immudb today.](https:\u002F\u002Fwww.immudb.io)\n\n\n## Contents\n\n- [immudb](#immudb)\n  - [Contents](#contents)\n  - [Quickstart](#quickstart)\n  - [Recent Changes](#recent-changes)\n    - [Structured Audit Logging](#structured-audit-logging)\n    - [DIFF OF SQL Query](#diff-of-sql-query)\n    - [PostgreSQL SQL Compatibility](#postgresql-sql-compatibility)\n    - [Security Hardening](#security-hardening)\n  - [Using immudb](#using-immudb)\n  - [Tech specs](#tech-specs)\n  - [Performance figures](#performance-figures)\n  - [Roadmap](#roadmap)\n  - [Projects using immudb](#projects-using-immudb)\n  - [Contributing](#contributing)\n\n## Quickstart\n\n\n### Getting immudb running: executable\n\nYou may download the immudb binary from [the latest releases on Github](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Freleases\u002Flatest). Once you have downloaded immudb, rename it to `immudb`, make sure to mark it as executable, then run it. The following example shows how to obtain v1.9.5 for linux amd64:\n\n```bash\nwget https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Freleases\u002Fdownload\u002Fv1.9.5\u002Fimmudb-v1.9.5-linux-amd64\nmv immudb-v1.9.5-linux-amd64 immudb\nchmod +x immudb\n\n# run immudb in the foreground to see all output\n.\u002Fimmudb\n\n# or run immudb in the background\n.\u002Fimmudb -d\n```\n\n### Getting immudb running: Docker\n\nUse Docker to run immudb in a ready-to-use container:\n\n```bash\ndocker run -d --net host -it --rm --name immudb codenotary\u002Fimmudb:latest\n```\n\nIf you are running the Docker image without host networking, make sure to expose ports 3322 and 9497.\n\n### Getting immudb running: Kubernetes\n\nIn kubernetes, use helm for an easy deployment: just add our repository and install immudb with these simple commands:\n\n```bash\nhelm repo add immudb https:\u002F\u002Fpackages.codenotary.org\u002Fhelm\nhelm repo update\nhelm install immudb\u002Fimmudb --generate-name\n```\n\n### Using subfolders\n\nImmudb helm chart creates a persistent volume for storing immudb database.\nThose database are now by default placed in a subdirectory.\n\nThat's for compatibility with ext4 volumes that have a `\u002Flost+found` directory that can confuse immudb. Some volume providers,\nlike EBS or DigitalOcean, are using this kind of volumes. If we placed database directory on the root of the volume,\nthat `\u002Flost+found` would be treated as a database. So we now create a subpath (usually `immudb`) subpath for storing that.\n\nThis is different from what we did on older (\u003C=1.3.1) helm charts, so if you have already some volumes with data you can set\nvalue volumeSubPath to false (i.e.: `--set volumeSubPath.enabled=false`) when upgrading so that the old way is used.\n\nYou can alternatively migrate the data in a `\u002Fimmudb` directory. You can use this pod as a reference for the job:\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: migrator\nspec:\n  volumes:\n    - name: \"vol0\"\n      persistentVolumeClaim:\n        claimName: \u003Cyour-claim-name-here>\n  containers:\n    - name: migrator\n      image: busybox\n      volumeMounts:\n        - mountPath: \"\u002Fdata\"\n          name: \"vol0\"\n      command:\n        - sh\n        - -c\n        - |\n          mkdir -p \u002Fdata\u002Fimmudb\n          ls \u002Fdata | grep -v -E 'immudb|lost\\+found'|while read i; do mv \u002Fdata\u002F$i \u002Fdata\u002Fimmudb\u002F$i; done\n```\n\nAs said before, you can totally disable the use of subPath by setting `volumeSubPath.enabled=false`.\nYou can also tune the subfolder path using `volumeSubPath.path` value, if you prefer your data on a\ndifferent directory than the default `immudb`.\n\n### Enabling Amazon S3 storage\n\nimmudb can store its data in the Amazon S3 service (or a compatible alternative).\nThe following example shows how to run immudb with the S3 storage enabled:\n\n```bash\nexport IMMUDB_S3_STORAGE=true\nexport IMMUDB_S3_ACCESS_KEY_ID=\u003CS3 ACCESS KEY ID>\nexport IMMUDB_S3_SECRET_KEY=\u003CSECRET KEY>\nexport IMMUDB_S3_BUCKET_NAME=\u003CBUCKET NAME>\nexport IMMUDB_S3_LOCATION=\u003CAWS S3 REGION>\nexport IMMUDB_S3_PATH_PREFIX=testing-001\nexport IMMUDB_S3_ENDPOINT=\"https:\u002F\u002F${IMMUDB_S3_BUCKET_NAME}.s3.${IMMUDB_S3_LOCATION}.amazonaws.com\"\n\n.\u002Fimmudb\n```\n\nWhen working with the external storage, you can enable the option for the remote storage\nto be the primary source of identifier. This way, if immudb is run using ephemeral disks,\nsuch as with AWS ECS Fargate, the identifier can be taken from S3. To enable that, use:\n\n```bash\nexport IMMUDB_S3_EXTERNAL_IDENTIFIER=true\n```\n\nYou can also use the role-based credentials for more flexible and secure configuration.\nThis allows the service to be used with instance role configuration without a user entity.\nThe following example shows how to run immudb with the S3 storage enabled using AWS Roles:\n\n```bash\nexport IMMUDB_S3_STORAGE=true\nexport IMMUDB_S3_ROLE_ENABLED=true\nexport IMMUDB_S3_BUCKET_NAME=\u003CBUCKET NAME>\nexport IMMUDB_S3_LOCATION=\u003CAWS S3 REGION>\nexport IMMUDB_S3_PATH_PREFIX=testing-001\nexport IMMUDB_S3_ENDPOINT=\"https:\u002F\u002F${IMMUDB_S3_BUCKET_NAME}.s3.${IMMUDB_S3_LOCATION}.amazonaws.com\"\n\n.\u002Fimmudb\n```\n\nIf using Fargate, the credentials URL can be sourced automatically:\n\n```bash\nexport IMMUDB_S3_USE_FARGATE_CREDENTIALS=true\n```\n\nOptionally, you can specify the exact role immudb should be using with:\n\n```bash\nexport IMMUDB_S3_ROLE=\u003CAWS S3 ACCESS ROLE NAME>\n```\n\nRemember, the `IMMUDB_S3_ROLE_ENABLED` parameter still should be on.\n\nYou can also easily use immudb with compatible s3 alternatives\nsuch as the [minio](https:\u002F\u002Fgithub.com\u002Fminio\u002Fminio) server:\n\n```bash\nexport IMMUDB_S3_ACCESS_KEY_ID=minioadmin\nexport IMMUDB_S3_SECRET_KEY=minioadmin\nexport IMMUDB_S3_STORAGE=true\nexport IMMUDB_S3_BUCKET_NAME=immudb-bucket\nexport IMMUDB_S3_PATH_PREFIX=testing-001\nexport IMMUDB_S3_ENDPOINT=\"http:\u002F\u002Flocalhost:9000\"\n\n# Note: This spawns a temporary minio server without data persistence\ndocker run -d -p 9000:9000 minio\u002Fminio server \u002Fdata\n\n# Create the bucket - this can also be done through web console at http:\u002F\u002Flocalhost:9000\ndocker run --net=host -it --entrypoint \u002Fbin\u002Fsh minio\u002Fmc -c \"\n  mc alias set local http:\u002F\u002Flocalhost:9000 minioadmin minioadmin &&\n  mc mb local\u002F${IMMUDB_S3_BUCKET_NAME}\n\"\n\n# Run immudb instance\n.\u002Fimmudb\n```\n\n### Connecting with immuclient\n\nYou may download the immuclient binary from [the latest releases on Github](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Freleases\u002Flatest). Once you have downloaded immuclient, rename it to `immuclient`, make sure to mark it as executable, then run it. The following example shows how to obtain v1.5.0 for linux amd64:\n\n```bash\nwget https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Freleases\u002Fdownload\u002Fv1.5.0\u002Fimmuclient-v1.5.0-linux-amd64\nmv immuclient-v1.5.0-linux-amd64 immuclient\nchmod +x immuclient\n\n# start the interactive shell\n.\u002Fimmuclient\n\n# or use commands directly\n.\u002Fimmuclient help\n```\n\nOr just use Docker to run immuclient in a ready-to-use container. Nice and simple.\n\n```bash\ndocker run -it --rm --net host --name immuclient codenotary\u002Fimmuclient:latest\n```\n\n\n## Recent Changes\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Structured Audit Logging\u003C\u002Fb>\u003C\u002Fsummary>\n\n\nimmudb now supports immutable, structured audit logging of all server operations. When enabled, every gRPC operation is recorded as a JSON audit event stored in immudb's own tamper-proof KV store under the `audit:` key prefix.\n\n**Enable audit logging:**\n\n```bash\n# Log all operations\n.\u002Fimmudb --audit-log\n\n# Log only write, admin, auth, and system operations (exclude reads)\n.\u002Fimmudb --audit-log --audit-log-events=write\n\n# Log only admin, auth, and system operations\n.\u002Fimmudb --audit-log --audit-log-events=admin\n```\n\nEach audit event captures:\n\n| Field     | Description                                      |\n| --------- | ------------------------------------------------ |\n| `ts`      | Nanosecond timestamp                             |\n| `user`    | Authenticated username                           |\n| `ip`      | Client IP address                                |\n| `db`      | Target database                                  |\n| `method`  | gRPC method name                                 |\n| `type`    | Event category: AUTH, ADMIN, WRITE, READ, SYSTEM |\n| `ok`      | Whether the operation succeeded                  |\n| `err`     | Error message (if failed)                        |\n| `dur_ms`  | Operation duration in milliseconds               |\n| `sid`     | Session ID                                       |\n\nAudit events are written asynchronously to avoid impacting request latency. They can be queried using the standard `Scan` API with prefix `audit:` and verified with `VerifiableGet` for tamper-proof compliance evidence. Events are stored as JSON, ready for export to external SIEM systems (Splunk, ELK, etc.).\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>DIFF OF SQL Query\u003C\u002Fb>\u003C\u002Fsummary>\n\n\nimmudb now supports comparing table state between two points in time using the new `DIFF OF` SQL syntax:\n\n```sql\nSELECT _diff_action, id, title, active FROM (DIFF OF mytable) SINCE TX 100 UNTIL TX 200\n```\n\nThe `_diff_action` column indicates whether each row was an `INSERT`, `UPDATE`, or `DELETE` within the specified transaction range. Both `SINCE`\u002F`AFTER` and `UNTIL`\u002F`BEFORE` period specifiers are supported. Standard `WHERE` clauses can be applied to filter results.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>PostgreSQL SQL Compatibility\u003C\u002Fb>\u003C\u002Fsummary>\n\n\nimmudb's PostgreSQL wire protocol server now supports a comprehensive set of SQL features for ORM and tool compatibility. Connect with any PostgreSQL client (`psql`, pgAdmin, JDBC, SQLAlchemy, Django, GORM, ActiveRecord) and use standard SQL.\n\n**RETURNING clause** for INSERT, UPDATE, and DELETE:\n\n```sql\nINSERT INTO users (name) VALUES ('Alice') RETURNING id, name;\nUPDATE users SET name = 'Bob' WHERE id = 1 RETURNING *;\nDELETE FROM users WHERE id = 1 RETURNING *;\n```\n\n**Common Table Expressions (WITH \u002F WITH RECURSIVE)**:\n\n```sql\nWITH RECURSIVE tree AS (\n    SELECT id, name FROM nodes WHERE parent_id = 0\n    UNION ALL\n    SELECT n.id, n.name FROM nodes n INNER JOIN tree t ON n.parent_id = t.id\n)\nSELECT * FROM tree;\n```\n\n**Window functions**:\n\n```sql\nSELECT name, dept,\n    ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) rank,\n    SUM(salary) OVER (PARTITION BY dept) dept_total,\n    LAG(salary) OVER (ORDER BY salary) prev_salary\nFROM employees;\n```\n\nSupported window functions: `ROW_NUMBER`, `RANK`, `DENSE_RANK`, `LAG`, `LEAD`, `FIRST_VALUE`, `LAST_VALUE`, `NTILE`, and window aggregates (`COUNT`, `SUM`, `MIN`, `MAX`, `AVG`).\n\n**Views and Sequences**:\n\n```sql\nCREATE VIEW active_users AS SELECT * FROM users WHERE active = true;\nCREATE SEQUENCE order_seq;\nSELECT NEXTVAL('order_seq');\n```\n\n**Full SQL feature set**:\n\n| Category | Features |\n|----------|----------|\n| Joins | INNER, LEFT, RIGHT, CROSS, FULL OUTER, NATURAL, USING |\n| Subqueries | EXISTS, IN, NOT EXISTS, NOT IN (correlated and non-correlated) |\n| Set operations | UNION, UNION ALL, EXCEPT, INTERSECT |\n| DML | INSERT...ON CONFLICT DO UPDATE, INSERT\u002FUPDATE\u002FDELETE...RETURNING |\n| DDL | CREATE\u002FDROP VIEW, CREATE\u002FDROP SEQUENCE, ALTER COLUMN, FOREIGN KEY |\n| Ordering | ORDER BY with NULLS FIRST\u002FLAST, LIMIT ALL |\n| Pattern matching | LIKE, ILIKE (case-insensitive) -- standard SQL wildcards (`%` and `_`) |\n| Query analysis | EXPLAIN |\n| Aggregates | COUNT, SUM, MIN, MAX, AVG, COUNT(DISTINCT col), STRING_AGG(col, separator) |\n| Type aliases | BIGINT, INT, SMALLINT, SERIAL, DOUBLE, REAL, NUMERIC, DECIMAL, BYTEA, JSONB, TIMESTAMPTZ, and more |\n| Transactions | BEGIN, COMMIT, ROLLBACK, SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT |\n| Data import | COPY FROM stdin (bulk import via psql \u002F pg_dump) |\n| LATERAL joins | Correlated subqueries in FROM clause |\n| Partial indexes | CREATE INDEX ... WHERE condition |\n\n**75+ built-in functions** including:\n\n- Math: `ABS`, `CEIL`, `FLOOR`, `ROUND`, `POWER`, `SQRT`, `MOD`, `SIGN`\n- String: `CONCAT`, `CONCAT_WS`, `REPLACE`, `REVERSE`, `LEFT`, `RIGHT`, `LPAD`, `RPAD`, `SPLIT_PART`, `INITCAP`, `REPEAT`, `POSITION`, `MD5`, `REGEXP_REPLACE`, `TRANSLATE`\n- Date\u002FTime: `NOW`, `DATE_TRUNC`, `TO_CHAR`, `DATE_PART`, `AGE`, `EXTRACT`\n- Conditional: `COALESCE`, `NULLIF`, `GREATEST`, `LEAST`, `CASE`\n- Aggregate: `STRING_AGG`, `COUNT(DISTINCT col)`\n- PG compatibility: `current_database()`, `current_schema()`, `current_user`, `format_type()`, `pg_encoding_to_char()`\n\n**Immutable verification via SQL** -- query immudb's cryptographic proof system directly:\n\n```sql\nSELECT immudb_state();                         -- current database state and tx hash\nSELECT immudb_verify_row('mytable', 1);        -- cryptographically verify a row\nSELECT immudb_verify_tx(42);                   -- verify a transaction with proof\nSELECT immudb_history('mykey');                -- full history of a key\n```\n\n**ORM introspection support** with `pg_catalog` tables (`pg_class`, `pg_attribute`, `pg_index`, `pg_constraint`, `pg_type`, `pg_namespace`, `pg_roles`, `pg_settings`, `pg_description`) and `information_schema` views (`tables`, `columns`, `schemata`, `key_column_usage`).\n\n**Known limitations** -- the following PostgreSQL features are not yet supported:\n\n| Feature | Reason |\n|---------|--------|\n| Generated columns (`GENERATED ALWAYS AS`) | Requires computed column infrastructure |\n| Stored procedures \u002F PL\u002FpgSQL | Requires a language interpreter |\n| GIN\u002FGiST indexes | Only B-tree indexes currently supported |\n| ARRAY, ENUM, composite types | Limited to 9 base types with aliases |\n| `SUM(a * b)` expressions inside aggregates | Arithmetic not supported inside aggregate functions |\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>ORM and Application Compatibility\u003C\u002Fb>\u003C\u002Fsummary>\n\n\nThis branch significantly hardens the PostgreSQL wire protocol and SQL engine against the corner cases that real-world ORMs and applications hit. Verified workloads now include **Gitea 1.25.5** (full signup → repo creation → git push → issue lifecycle), **Ruby on Rails 7 \u002F ActiveRecord** (Maybe Finance dashboard), **Django**, **GORM**, **XORM**, **golang-migrate**, **SQLAlchemy**, **lib\u002Fpq** and **pgx** drivers.\n\n**System catalog and introspection emulation** -- ORMs probe these on every connection; immudb returns realistic results for:\n\n- `pg_catalog`: `pg_class`, `pg_attribute`, `pg_index`, `pg_indexes`, `pg_constraint`, `pg_type`, `pg_namespace`, `pg_roles`, `pg_settings`, `pg_description`, `pg_tables`\n- `information_schema`: `tables`, `columns`, `schemata`, `key_column_usage`\n- Function emulation: `current_database()`, `current_schema()`, `current_user`, `format_type()`, `pg_encoding_to_char()`, `pg_get_indexdef()`, `regclass`\u002F`regtype` casts\n- XORM column-introspection short-circuit so schema syncs don't issue thousands of slow catalog reads\n\n**Reserved-keyword identifier round-trip** -- ORMs that quote `\"index\"`, `\"key\"`, `\"value\"`, `\"user\"`, `\"order\"`, `\"check\"`, etc. now Just Work. Quoted identifiers map to a `_\u003Cword>` column on disk, and the wire layer reverse-renames them on the way out so client struct mappers see the original name.\n\n**Parameter-bind protocol fixes** -- correct text- and binary-format handling for every Postgres type immudb supports:\n\n- `BYTEA` in canonical PG hex format (`\\x\u003Chex>`) for both bind and result paths\n- `BOOLEAN` accepts `t`\u002F`f`, `true`\u002F`false`, `1`\u002F`0`\n- `TIMESTAMP` accepts the Rails-style `YYYY-MM-DD HH:MM:SS.ffffff` text form\n- `FLOAT8`, `INT8`, `JSONB`, `TIMESTAMPTZ` OIDs in `RowDescription` for ORM type inference\n- `NULL` binds across all types\n- Implicit `VARCHAR → BOOLEAN` coercion for ORMs that never declare a parameter type\n- Bind type inference recurses into subquery expressions (`IN (SELECT …)`, scalar subqueries, `EXISTS`, `CASE WHEN`, `EXTRACT`, `ORDER BY` with bind params), so `lib\u002Fpq`'s ParameterDescription matches what the client is about to send\n\n**SQL grammar additions and fixes** for ORM-emitted shapes:\n\n- Unqualified column references inside `JOIN`\u002F`WHERE` resolve across all FROM-scope tables (XORM emits `JOIN issue_assignees ON assignee_id = user.id` without table qualifier)\n- Scalar subqueries usable in `WHERE`, `SELECT` projection, and `ORDER BY`\n- `COUNT(DISTINCT col)`, `COUNT(1)` (rewritten to `COUNT(*)`), `STRING_AGG(col, sep)`, `SUM(CASE WHEN col = ? THEN 1 ELSE 0 END)` (rewritten when the shape matches)\n- Alias names that match aggregate keywords (`SELECT id AS sum FROM …`)\n- `LIKE` \u002F `ILIKE` with standard SQL wildcards (`%`, `_`)\n- Hash aggregate path for `GROUP BY` without sorted input; projection pushdown that skips decoding columns the query doesn't reference; secondary index used for `WHERE`-only `SELECT`\n\n**DML correctness** -- semantics now match Postgres for the patterns ORMs rely on most:\n\n- `INSERT … ON CONFLICT DO UPDATE SET col = expr` reads the EXISTING row's values when reducing `expr` (so per-group counters like XORM's `max_index = max_index + 1` actually increment)\n- `RETURNING` capture is reset on every prepared-statement re-execution (so reused INSERTs over Bind\u002FExecute don't return stale rows from earlier executions)\n- `INSERT INTO schema_migrations` is automatically idempotent (`ON CONFLICT DO NOTHING`) so Rails \u002F golang-migrate can re-run schema syncs safely\n- Multi-statement transactions, `SAVEPOINT` \u002F `ROLLBACK TO SAVEPOINT`, and explicit `BEGIN` \u002F `COMMIT` \u002F `ROLLBACK` track transaction status correctly so `lib\u002Fpq` and `pgx` accept the next query\n\n**Logging and operability** -- benign client disconnects (Rails connection-pool churn, Gitea eventsource long-poll cancels) demoted from `[E]` to debug; per-session SQL parse cache and in-memory catalog cache reduce per-query overhead under ORM workloads.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Security Hardening\u003C\u002Fb>\u003C\u002Fsummary>\n\n\n- **Path traversal protection**: Archive restore now validates extraction paths, rejecting entries that attempt directory escape via `..` or absolute paths.\n- **Session invalidation**: User deactivation, password changes, permission changes, and SQL privilege changes now immediately terminate all active sessions for the affected user.\n- **Token file permissions**: Client authentication tokens are now written with `0600` permissions (owner-only) instead of `0644`.\n- **PgSQL TLS warning**: The PostgreSQL-compatible server now logs a warning at startup when running without TLS, as cleartext password authentication is used.\n\n\u003C\u002Fdetails>\n\n## Using immudb\n\nLot of useful documentation and step by step guides can be found at https:\u002F\u002Fdocs.immudb.io\u002F\n\n### Real world examples\n\nWe already learned about the following use cases from users:\n\n- use immudb to immutably store every update to sensitive database fields (credit card or bank account data) of an existing application database\n- store CI\u002FCD recipes in immudb to protect build and deployment pipelines\n- store public certificates in immudb\n- use immudb as an additional hash storage for digital objects checksums\n- store log streams (i. e. audit logs) tamperproof\n- store the last known positions of submarines\n- record the location where fish was found aboard fishing trawlers\n\n### How to integrate immudb in your application\n\nWe have SDKs available for the following programming languages:\n\n1. Java [immudb4j](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb4j)\n2. Golang ([golang sdk](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Fpkg\u002Fclient), [Gorm adapter](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmugorm))\n3. .net [immudb4net](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb4net)\n4. Python [immudb-py](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb-py)\n5. Node.js [immudb-node](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb-node)\n\nTo get started with development, there is a [quickstart in our documentation](https:\u002F\u002Fdocs.immudb.io\u002Fmaster\u002Fimmudb.html): or pick a basic running sample from [immudb-client-examples](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb-client-examples).\n\nOur [immudb Playground](https:\u002F\u002Fplay.codenotary.com) provides a guided environment to learn the Python SDK.\n\n\u003Cdiv align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fplay.codenotary.com\">\n    \u003Cimg alt=\"immudb playground to start using immudb in an online demo environment\" src=\"img\u002Fplayground2.png\"\u002F>\n  \u003C\u002Fa>\n\u003C\u002Fdiv>\n\nWe've developed a \"language-agnostic SDK\" which exposes a REST API for easy consumption by any application.\n[immugw](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmugw) may be a convenient tool when SDKs are not available for the\nprogramming language you're using, for experimentation, or just because you prefer your app only uses REST endpoints.\n\n### Online demo environment\n\nClick here to try out the immudb web console access in an [online demo environment](https:\u002F\u002Fdemo.immudb.io) (username: immudb; password: immudb)\n\n\u003Cdiv align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fdemo.immudb.io\">\n    \u003Cimg alt=\"Your own temporary immudb web console access to start using immudb in an online demo environment\" src=\"img\u002Fdemoimmudb.png\"\u002F>\n  \u003C\u002Fa>\n\u003C\u002Fdiv>\n\n## Tech specs\n\n| Topic                   | Description                                         |\n| ----------------------- | --------------------------------------------------- |\n| DB Model                | Key-Value with 3D access, Document Model, SQL       |\n| Data scheme             | schema-free                                         |\n| Implementation design   | Cryptographic commit log with parallel Merkle Tree, |\n|                         | (sync\u002Fasync) indexing with extended B-tree          |\n| Implementation language | Go                                                  |\n| Server OS(s)            | BSD, Linux, OS X, Solaris, Windows, IBM z\u002FOS        |\n| Embeddable              | Yes, optionally                                     |\n| Server APIs             | gRPC, PostgreSQL wire protocol (v3)                 |\n| Partition methods       | Sharding                                            |\n| Consistency concepts    | Immediate Consistency                               |\n| Transaction concepts    | ACID with Snapshot Isolation (SSI)                  |\n| Durability              | Yes                                                 |\n| Snapshots               | Yes                                                 |\n| High Read throughput    | Yes                                                 |\n| High Write throughput   | Yes                                                 |\n| Optimized for SSD       | Yes                                                 |\n\n## Performance figures\n\nimmudb can handle millions of writes per second. The following table shows performance of the embedded store inserting 1M entries on a machine with 4-core E3-1275v6 CPU and SSD disk:\n\n| Entries | Workers | Batch | Batches | time (s) | Entries\u002Fs |\n| ------- | ------- | ----- | ------- | -------- | --------- |\n| 1M      | 20      | 1000  | 50      | 1.061    | 1.2M \u002Fs   |\n| 1M      | 50      | 1000  | 20      | 0.543    | 1.8M \u002Fs   |\n| 1M      | 100     | 1000  | 10      | 0.615    | 1.6M \u002Fs   |\n\nYou can generate your own benchmarks using the `stress_tool` under `embedded\u002Ftools`.\n\n## Roadmap\n\nThe following topics are important to us and are planned or already being worked on:\n\n* Data pruning\n* Compression\n* compatibility with other database storage files\n* Easier API for developers\n* API compatibility with other, well-known embedded databases\n\n## Projects using immudb\n\nBelow is a list of known projects that use immudb:\n\n- [alma-sbom](https:\u002F\u002Fgithub.com\u002FAlmaLinux\u002Falma-sbom) - AlmaLinux OS SBOM data management utility.\n\n- [immudb-log-audit](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb-log-audit) - A service and cli tool to store json formatted log input\n  and audit it later in immudb Vault.\n\n- [immudb-operator](https:\u002F\u002Fgithub.com\u002Funagex\u002Fimmudb-operator) - Unagex Kubernetes Operator for immudb.\n\n- [immufluent](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmufluent) - Send fluentbit collected logs to immudb.\n\n- [immuvoting](https:\u002F\u002Fgithub.com\u002Fpadurean\u002Fimmuvoting) - Publicly cryptographically verifiable electronic voting system powered by immudb.\n\nAre you using immudb in your project? Open a pull request to add it to the list.\n\n## Contributing\n\nWe welcome [contributors](CONTRIBUTING.md). Feel free to join the team!\n\n\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Fgraphs\u002Fcontributors\">\n  \u003Cimg src=\"https:\u002F\u002Fcontrib.rocks\u002Fimage?repo=codenotary\u002Fimmudb\" \u002F>\n\u003C\u002Fa>\n\nLearn how to [build](BUILD.md) immudb components in both binary and Docker image form.\n\nTo report bugs or get help, use [GitHub's issues](https:\u002F\u002Fgithub.com\u002Fcodenotary\u002Fimmudb\u002Fissues).\n\nimmudb is licensed under the [Business Source License 1.1](LICENSE).\n\nimmudb re-distributes other open-source tools and libraries - [Acknowledgements](ACKNOWLEDGEMENTS.md).\n","immudb 是一个基于零信任原则构建的不可变数据库，支持SQL\u002F键值\u002F文档模型，具备防篡改和数据变更历史记录功能。该项目采用Go语言开发，核心特性包括数据加密、验证以及时间旅行查询等，确保了数据的完整性和可追溯性。相比传统数据库，immudb 通过其不变性设计，使得一旦数据被写入便无法修改或删除，从而为关键信息提供了一层额外的安全保障。适用于需要高度安全性和合规性的场景，如审计日志保存、敏感数据管理及软件构建过程中的证据保存等。","2026-06-11 03:02:37","top_language"]