rubydb 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile.lock +1 -1
  5. data/README.md +296 -227
  6. data/Rakefile +6 -1
  7. data/accelerator/bin/SHA256SUMS +6 -0
  8. data/accelerator/bin/rubydb-accelerator-darwin-amd64 +0 -0
  9. data/accelerator/bin/rubydb-accelerator-darwin-arm64 +0 -0
  10. data/accelerator/bin/rubydb-accelerator-linux-amd64 +0 -0
  11. data/accelerator/bin/rubydb-accelerator-linux-arm64 +0 -0
  12. data/accelerator/bin/rubydb-accelerator-windows-amd64.exe +0 -0
  13. data/accelerator/bin/rubydb-accelerator-windows-arm64.exe +0 -0
  14. data/accelerator/cmd/rubydb-accelerator/main.go +11 -0
  15. data/accelerator/go.mod +3 -0
  16. data/accelerator/internal/execution/aggregate.go +94 -0
  17. data/accelerator/internal/execution/distinct.go +22 -0
  18. data/accelerator/internal/execution/filter.go +73 -0
  19. data/accelerator/internal/execution/join.go +79 -0
  20. data/accelerator/internal/execution/operators.go +167 -0
  21. data/accelerator/internal/execution/scan.go +20 -0
  22. data/accelerator/internal/execution/sort.go +62 -0
  23. data/accelerator/internal/execution/types.go +136 -0
  24. data/accelerator/internal/execution/value.go +67 -0
  25. data/accelerator/internal/memory/arena.go +47 -0
  26. data/accelerator/internal/memory/reuse.go +22 -0
  27. data/accelerator/internal/metrics/registry.go +67 -0
  28. data/accelerator/internal/parallel/bounded_queue.go +56 -0
  29. data/accelerator/internal/parallel/scheduler.go +47 -0
  30. data/accelerator/internal/parallel/worker_pool.go +53 -0
  31. data/accelerator/internal/protocol/cancellation.go +48 -0
  32. data/accelerator/internal/protocol/columnar.go +263 -0
  33. data/accelerator/internal/protocol/frame.go +187 -0
  34. data/accelerator/internal/runtime/worker.go +521 -0
  35. data/accelerator/internal/storage/page_reader.go +81 -0
  36. data/accelerator/internal/storage/snapshot_scan.go +539 -0
  37. data/accelerator/internal/wal/checksum.go +13 -0
  38. data/accelerator/internal/wal/compression.go +41 -0
  39. data/accelerator/internal/wal/group_commit.go +24 -0
  40. data/accelerator/internal/wal/record_encoder.go +40 -0
  41. data/adapters/activerecord/README.md +8 -3
  42. data/adapters/activerecord/lib/active_record/connection_adapters/rubydb_adapter.rb +50 -42
  43. data/adapters/activerecord/rubydb-activerecord.gemspec +1 -1
  44. data/docs/README.md +3 -1
  45. data/docs/architecture/go-accelerator.md +179 -0
  46. data/docs/cli.md +24 -0
  47. data/docs/contributing/benchmarking.md +16 -0
  48. data/docs/developer/local-development.md +32 -0
  49. data/docs/release.md +2 -2
  50. data/lessons/02-local-development.md +2 -2
  51. data/lessons/04-rails-complex-apps.md +2 -2
  52. data/lessons/05-rubydb-production-server.md +2 -2
  53. data/lessons/07-hybrid-microservices.md +175 -90
  54. data/lessons/10-release-readiness.md +184 -117
  55. data/lessons/11-community-adapter.md +323 -0
  56. data/lessons/12-rails-ecommerce-pressure.md +263 -0
  57. data/lib/rubydb/accelerator/client.rb +451 -0
  58. data/lib/rubydb/accelerator/error.rb +22 -0
  59. data/lib/rubydb/accelerator/manager.rb +606 -0
  60. data/lib/rubydb/accelerator.rb +13 -0
  61. data/lib/rubydb/cli/application.rb +6 -1
  62. data/lib/rubydb/cli/commands/accelerator.rb +72 -0
  63. data/lib/rubydb/cli/commands/doctor.rb +3 -0
  64. data/lib/rubydb/client/client.rb +7 -0
  65. data/lib/rubydb/client/connection.rb +15 -0
  66. data/lib/rubydb/client/result.rb +5 -1
  67. data/lib/rubydb/configuration/defaults.rb +12 -0
  68. data/lib/rubydb/configuration/validation.rb +8 -1
  69. data/lib/rubydb/execution/accelerator_dispatch.rb +30 -0
  70. data/lib/rubydb/execution/cost_model.rb +72 -0
  71. data/lib/rubydb/execution/executor.rb +373 -11
  72. data/lib/rubydb/execution/operator_selection.rb +57 -0
  73. data/lib/rubydb/execution/physical_plan.rb +47 -0
  74. data/lib/rubydb/execution/planner.rb +12 -46
  75. data/lib/rubydb/execution/sort_executor.rb +22 -8
  76. data/lib/rubydb/indexes/btree.rb +31 -2
  77. data/lib/rubydb/rubydb.rb +7 -1
  78. data/lib/rubydb/server/session.rb +45 -0
  79. data/lib/rubydb/storage/engine.rb +74 -12
  80. data/lib/rubydb/storage/snapshot_reader.rb +167 -0
  81. data/lib/rubydb/version.rb +1 -1
  82. data/lib/rubydb/wal/archive.rb +17 -0
  83. data/lib/rubydb/wal/wal.rb +1 -0
  84. data/rubydb.gemspec +12 -2
  85. data/scripts/build_accelerator +49 -0
  86. data/scripts/release +34 -4
  87. data/scripts/replication_failover_drill +2 -2
  88. metadata +49 -1
@@ -1,94 +1,179 @@
1
- # Lesson 7: a hybrid microservice architecture
2
-
3
- A practical RubyDB architecture is to keep the large shared business system
4
- on PostgreSQL and use RubyDB for a small service with a narrow responsibility.
5
- Examples include a local catalog, a bounded document/index service, an
6
- internal workflow, or a tenant-isolated tool whose SQL and recovery needs have
7
- been validated.
8
-
9
- ## Give each service ownership
10
-
11
- ```text
12
- Rails monolith / public API
13
- |
14
- +--> PostgreSQL: users, billing, orders, reporting
15
- |
16
- +--> RubyDB service API: bounded internal records
17
- |
18
- +--> one RubyDB server and persistent data directory
19
- ```
20
-
21
- The services communicate through an API or an event contract. They do not
22
- share an embedded file and they do not write directly into each other’s tables.
23
- Each service owns its migrations, credentials, backups, alerts, and recovery
24
- runbook.
25
-
26
- ## Ruby client for a service
27
-
28
- ```ruby
29
- # app/services/catalog_store.rb
30
- require "rubydb"
31
-
32
- class CatalogStore
33
- def initialize(url: ENV.fetch("RUBYDB_URL"))
34
- @client = RubyDB::Client::Client.new(url: url)
35
- end
36
-
37
- def find(code)
38
- result = @client.query(
39
- "SELECT code, title FROM catalog_items WHERE code = ?",
40
- [code]
41
- )
42
- result.to_a.first
43
- end
44
-
45
- def close
46
- @client.disconnect
47
- end
48
- end
1
+ # Lesson 7: a hybrid microservice architecture
2
+
3
+ A practical RubyDB architecture is to keep the large shared business system
4
+ on PostgreSQL and use RubyDB for a small service with a narrow responsibility.
5
+ Examples include a local catalog, a bounded document/index service, an
6
+ internal workflow, or a tenant-isolated tool whose SQL and recovery needs have
7
+ been validated.
8
+
9
+ ## Give each service ownership
10
+
11
+ ```text
12
+ Rails monolith / public API
13
+ |
14
+ +--> PostgreSQL: users, billing, orders, reporting
15
+ |
16
+ +--> RubyDB service API: bounded internal records
17
+ |
18
+ +--> one RubyDB server and persistent data directory
19
+ ```
20
+
21
+ The services communicate through an API or an event contract. They do not
22
+ share an embedded file and they do not write directly into each other’s tables.
23
+ Each service owns its migrations, credentials, backups, alerts, and recovery
24
+ runbook.
25
+
26
+ ## Ruby client for a service
27
+
28
+ ```ruby
29
+ # app/services/catalog_store.rb
30
+ require "rubydb"
31
+
32
+ class CatalogStore
33
+ def initialize(url: ENV.fetch("RUBYDB_URL"))
34
+ @client = RubyDB::Client::Client.new(url: url)
35
+ end
36
+
37
+ def find(code)
38
+ result = @client.query(
39
+ "SELECT code, title FROM catalog_items WHERE code = ?",
40
+ [code]
41
+ )
42
+ result.to_a.first
43
+ end
44
+
45
+ def close
46
+ @client.disconnect
47
+ end
48
+ end
49
+ ```
50
+
51
+ Use the actual client API in the version pinned by the service and add tests
52
+ for connection failures, timeouts, duplicate requests, and empty results. In a
53
+ long-running app, put client lifecycle management in the application’s
54
+ dependency/container layer and close it during shutdown.
55
+
56
+ ## Python services with the RubyDB adapter
57
+
58
+ Python applications connect to RubyDB server mode through the published
59
+ `rubydb-python` DB-API 2.0 adapter. The Python process must not open an
60
+ embedded `.rdb` file. Put the server URL in a secret-managed environment
61
+ variable:
62
+
63
+ ```powershell
64
+ $env:RUBYDB_URL = "rubydbs://service_user:URL_ENCODED_PASSWORD@rubydb.internal:7432/orders?verify_peer=true&ca_file=%2Fetc%2Frubydb%2Ftls%2Fca.crt"
65
+ python -m pip install rubydb-python
66
+ ```
67
+
68
+ Use parameterized queries and a bounded pool in workers:
69
+
70
+ ```python
71
+ import os
72
+ from rubydb import ConnectionPool
73
+
74
+ pool = ConnectionPool(os.environ["RUBYDB_URL"], min_size=1, max_size=8)
75
+ try:
76
+ with pool.connection() as connection:
77
+ with connection.cursor() as cursor:
78
+ cursor.execute(
79
+ "SELECT id, status FROM jobs WHERE account_id = ?",
80
+ [account_id],
81
+ )
82
+ rows = cursor.fetchall()
83
+ finally:
84
+ pool.close()
85
+ ```
86
+
87
+ The adapter is synchronous DB-API code. In an async framework such as Flaxon,
88
+ run database calls in a worker thread so a slow query does not block the event
89
+ loop:
90
+
91
+ ```python
92
+ import asyncio
93
+ from rubydb import connect
94
+
95
+ async def load_jobs(url):
96
+ def query():
97
+ with connect(url, timeout=5) as db:
98
+ with db.cursor() as cursor:
99
+ cursor.execute("SELECT id, status FROM jobs ORDER BY id")
100
+ return cursor.fetchall()
101
+
102
+ return await asyncio.to_thread(query)
103
+ ```
104
+
105
+ Run the complete examples in `examples/python_flask` and
106
+ `examples/python_flaxon`. Both examples use real RubyDB TCP traffic and have
107
+ live integration tests; they are intentionally small starting points, not a
108
+ replacement for application-specific authorization, migrations, backups,
109
+ timeouts, monitoring, and load testing.
110
+
111
+ ## Node.js and TypeScript services
112
+
113
+ Node services use the `rubydb-node` package over the same RubyDB server
114
+ protocol:
115
+
116
+ ```sh
117
+ npm install rubydb-node
49
118
  ```
50
119
 
51
- Use the actual client API in the version pinned by the service and add tests
52
- for connection failures, timeouts, duplicate requests, and empty results. In a
53
- long-running app, put client lifecycle management in the application’s
54
- dependency/container layer and close it during shutdown.
55
-
56
- ## A small Rails service
57
-
58
- ```yaml
59
- # service/config/database.yml
60
- production:
61
- adapter: rubydb
62
- embedded: false
63
- url: <%= ENV.fetch("RUBYDB_URL") %>
64
- pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
120
+ ```ts
121
+ import { connect } from "rubydb-node";
122
+
123
+ const db = await connect(process.env.RUBYDB_URL!);
124
+ try {
125
+ const result = await db.query(
126
+ "SELECT id, state FROM jobs WHERE account_id = ?",
127
+ [accountId],
128
+ );
129
+ console.log(result.rows);
130
+ } finally {
131
+ await db.close();
132
+ }
65
133
  ```
66
134
 
67
- Keep the API idempotent. A client timeout can happen after the server commits
68
- a write, so a retry must use an idempotency key or first check the operation’s
69
- result. For cross-service workflows, record an outbox/event in the owning
70
- system and design consumers to tolerate duplicate delivery.
71
-
72
- ## What belongs where
73
-
74
- Keep users, payments, orders, and cross-tenant reporting in PostgreSQL when
75
- they need shared relational consistency and broad analytical tooling. Keep
76
- RubyDB data that can be independently backed up, restored, migrated, and
77
- reconciled. Do not split a single atomic business transaction across the two
78
- databases unless you have designed and tested a distributed workflow.
79
-
80
- ## Failure and deployment rules
81
-
82
- * Deploy the RubyDB service with a persistent volume and one server owner.
83
- * Make the service private; clients use TLS and least-privilege credentials.
84
- * Set bounded connection and request timeouts and expose a useful health probe.
85
- * Retry only idempotent operations, with backoff and a maximum attempt count.
86
- * Maintain a PostgreSQL and RubyDB restore drill independently.
87
- * Version the API/event contract before changing either database schema.
88
-
89
- ## Checkpoint
90
-
91
- The checkpoint passes when each data set has one owner, the API can tolerate a
92
- restarted database service, duplicate requests do not create duplicate business
93
- records, and the two systems can be restored independently. Continue to [lesson 8](08-migrations-backups-recovery.md)
94
- for migration and recovery drills.
135
+ Use `ConnectionPool` for concurrent workers, keep the pool bounded per process,
136
+ and use `rubydbs://` with peer verification in production. The package is
137
+ TypeScript-first, supports prepared statements, transactions, timeouts with
138
+ wire cancellation, and does not access embedded database files. See
139
+ `adapters/rubydb/README.md` for the full Node release and operations boundary.
140
+
141
+ ## A small Rails service
142
+
143
+ ```yaml
144
+ # service/config/database.yml
145
+ production:
146
+ adapter: rubydb
147
+ embedded: false
148
+ url: <%= ENV.fetch("RUBYDB_URL") %>
149
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
150
+ ```
151
+
152
+ Keep the API idempotent. A client timeout can happen after the server commits
153
+ a write, so a retry must use an idempotency key or first check the operation’s
154
+ result. For cross-service workflows, record an outbox/event in the owning
155
+ system and design consumers to tolerate duplicate delivery.
156
+
157
+ ## What belongs where
158
+
159
+ Keep users, payments, orders, and cross-tenant reporting in PostgreSQL when
160
+ they need shared relational consistency and broad analytical tooling. Keep
161
+ RubyDB data that can be independently backed up, restored, migrated, and
162
+ reconciled. Do not split a single atomic business transaction across the two
163
+ databases unless you have designed and tested a distributed workflow.
164
+
165
+ ## Failure and deployment rules
166
+
167
+ * Deploy the RubyDB service with a persistent volume and one server owner.
168
+ * Make the service private; clients use TLS and least-privilege credentials.
169
+ * Set bounded connection and request timeouts and expose a useful health probe.
170
+ * Retry only idempotent operations, with backoff and a maximum attempt count.
171
+ * Maintain a PostgreSQL and RubyDB restore drill independently.
172
+ * Version the API/event contract before changing either database schema.
173
+
174
+ ## Checkpoint
175
+
176
+ The checkpoint passes when each data set has one owner, the API can tolerate a
177
+ restarted database service, duplicate requests do not create duplicate business
178
+ records, and the two systems can be restored independently. Continue to [lesson 8](08-migrations-backups-recovery.md)
179
+ for migration and recovery drills.
@@ -1,125 +1,192 @@
1
- # Lesson 10: release readiness
2
-
3
- The final checkpoint is evidence, not optimism. A production release should
4
- identify the exact RubyDB and adapter versions, supported Ruby/Rails/OS matrix,
5
- tested SQL surface, backup artifact, restore result, load baseline, security
6
- review, and rollback owner.
7
-
8
- ## Run repository checks
9
-
10
- From the RubyDB repository:
11
-
12
- ```sh
13
- bundle install
14
- bundle exec rspec
15
- bundle exec rake
16
- git diff --check
17
- ```
18
-
19
- Run the Rails adapter suite from its directory and repeat it for every Rails
20
- and Ruby version you claim to support:
21
-
22
- ```sh
23
- cd adapters/activerecord
24
- bundle install
25
- bundle exec rspec
26
- ```
27
-
28
- Add your application’s complex query, migration, schema dump/load, concurrency,
29
- and failure tests to CI. A passing library suite does not certify an arbitrary
30
- application.
31
-
32
- ## Release a gem safely
33
-
34
- Review the project’s release instructions and run the preflight with a version
35
- that has not already been published:
36
-
37
- ```sh
38
- RUBYDB_RELEASE_VERSION=0.1.5 ruby scripts/release
39
- ```
40
-
41
- On PowerShell, use:
1
+ # Lesson 10: release readiness
2
+
3
+ The final checkpoint is evidence, not optimism. A production release should
4
+ identify the exact RubyDB and adapter versions, supported Ruby/Rails/OS matrix,
5
+ tested SQL surface, backup artifact, restore result, load baseline, security
6
+ review, and rollback owner.
7
+
8
+ ## Run repository checks
9
+
10
+ From the RubyDB repository:
11
+
12
+ ```sh
13
+ bundle install
14
+ bundle exec rspec
15
+ bundle exec rake
16
+ git diff --check
17
+ ```
18
+
19
+ Run the Rails adapter suite from its directory and repeat it for every Rails
20
+ and Ruby version you claim to support:
21
+
22
+ ```sh
23
+ cd adapters/activerecord
24
+ bundle install
25
+ bundle exec rspec
26
+ ```
27
+
28
+ Add your application’s complex query, migration, schema dump/load, concurrency,
29
+ and failure tests to CI. A passing library suite does not certify an arbitrary
30
+ application.
31
+
32
+ ## Release a gem safely
33
+
34
+ Review the project’s release instructions and run the preflight with a version
35
+ that has not already been published:
36
+
37
+ ```sh
38
+ RUBYDB_RELEASE_VERSION=0.1.6 ruby scripts/release
39
+ ```
40
+
41
+ On PowerShell, use:
42
+
43
+ ```powershell
44
+ $env:RUBYDB_RELEASE_VERSION = "0.1.6"
45
+ ruby scripts/release
46
+ ```
47
+
48
+ The release script builds the gem and writes a checksum. Check the artifact
49
+ locally before publishing:
50
+
51
+ ```sh
52
+ gem specification pkg/rubydb-0.1.6.gem
53
+ gem install pkg/rubydb-0.1.6.gem --local
54
+ ruby -rrubydb -e 'puts RubyDB::VERSION'
55
+ ```
56
+
57
+ Publishing requires a RubyGems API key or trusted publishing setup configured
58
+ on the release machine. The local script publishes only when both the explicit
59
+ publish flag and secret are present; never commit the secret:
60
+
61
+ ```sh
62
+ RUBYDB_RELEASE_VERSION=0.1.6 \
63
+ RUBYDB_PUBLISH=1 \
64
+ GEM_HOST_API_KEY="YOUR_RUBYGEMS_API_KEY" \
65
+ ruby scripts/release
66
+ ```
67
+
68
+ On Windows PowerShell:
69
+
70
+ ```powershell
71
+ $env:RUBYDB_RELEASE_VERSION = "0.1.6"
72
+ $env:RUBYDB_PUBLISH = "1"
73
+ $env:GEM_HOST_API_KEY = "YOUR_RUBYGEMS_API_KEY"
74
+ ruby scripts/release
75
+ ```
76
+
77
+ Prefer the repository’s signed GitHub Actions release workflow for a public
78
+ release. Store signing keys and RubyGems secrets only in protected secret
79
+ storage; do not put them in the repository or a checked-in `.env` file.
80
+
81
+ Release the adapter separately when its version changes, update the changelog,
82
+ tag the source commit, and publish the checksums and supported-version notes.
83
+
84
+ ## Publish the Python adapter to PyPI
85
+
86
+ The Python adapter is a separate distribution named `rubydb-python`; publishing
87
+ the Ruby gem does not publish this package. Build it from the adapter directory
88
+ and validate both distribution formats before upload:
89
+
90
+ ```powershell
91
+ cd adapters/python
92
+ python -m pip install --upgrade build twine
93
+ python -m build
94
+ python -m twine check dist/*
95
+ ```
96
+
97
+ Prefer PyPI Trusted Publishing from CI. For a local upload, use a short-lived,
98
+ scope-limited PyPI token through the environment or Twine's prompt. Never
99
+ commit a token:
100
+
101
+ ```powershell
102
+ $env:TWINE_USERNAME = "__token__"
103
+ $env:TWINE_PASSWORD = (Get-Clipboard).Trim()
104
+ python -m twine upload dist/*
105
+ Remove-Item Env:TWINE_PASSWORD
106
+ ```
107
+
108
+ After upload, verify the package from a clean environment and run the live
109
+ adapter tests against a RubyDB server:
110
+
111
+ ```powershell
112
+ python -m venv .venv-clean
113
+ .venv-clean\Scripts\Activate.ps1
114
+ python -m pip install rubydb-python
115
+ $env:RUBYDB_URL = "rubydbs://service_user:password@127.0.0.1:7432/rubydb"
116
+ python -m unittest discover -s adapters/python/tests -v
117
+ ```
118
+
119
+ The package provides DB-API 2.0 access to RubyDB server mode. It is not a
120
+ PostgreSQL driver and does not make PostgreSQL SQL portable to RubyDB. Pin the
121
+ adapter and server versions together, use TLS in production, and keep the
122
+ application's migration and rollback procedure under version control.
123
+
124
+ ## Build and publish the Node adapter
125
+
126
+ The Node adapter is a separate public npm package named `rubydb-node`. The
127
+ literal `node/rubydb` is not a valid npm name because npm reserves `/` for
128
+ scoped packages such as `@scope/package`.
42
129
 
43
130
  ```powershell
44
- $env:RUBYDB_RELEASE_VERSION = "0.1.5"
45
- ruby scripts/release
46
- ```
47
-
48
- The release script builds the gem and writes a checksum. Check the artifact
49
- locally before publishing:
50
-
51
- ```sh
52
- gem specification pkg/rubydb-0.1.5.gem
53
- gem install pkg/rubydb-0.1.5.gem --local
54
- ruby -rrubydb -e 'puts RubyDB::VERSION'
55
- ```
56
-
57
- Publishing requires a RubyGems API key or trusted publishing setup configured
58
- on the release machine. The local script publishes only when both the explicit
59
- publish flag and secret are present; never commit the secret:
60
-
61
- ```sh
62
- RUBYDB_RELEASE_VERSION=0.1.5 \
63
- RUBYDB_PUBLISH=1 \
64
- GEM_HOST_API_KEY="YOUR_RUBYGEMS_API_KEY" \
65
- ruby scripts/release
131
+ cd adapters/rubydb
132
+ npm ci
133
+ npm test
134
+ npm run publish:check
135
+ npm publish --access public
66
136
  ```
67
137
 
68
- On Windows PowerShell:
138
+ Use npm Trusted Publishing from CI or a protected npm token. Never commit an
139
+ `.npmrc` containing credentials. The package's live test runs against a real
140
+ RubyDB server when `RUBYDB_URL` is set:
69
141
 
70
142
  ```powershell
71
- $env:RUBYDB_RELEASE_VERSION = "0.1.5"
72
- $env:RUBYDB_PUBLISH = "1"
73
- $env:GEM_HOST_API_KEY = "YOUR_RUBYGEMS_API_KEY"
74
- ruby scripts/release
143
+ $env:RUBYDB_URL = "rubydb://rubydb@127.0.0.1:7432/rubydb"
144
+ npm test
75
145
  ```
76
146
 
77
- Prefer the repository’s signed GitHub Actions release workflow for a public
78
- release. Store signing keys and RubyGems secrets only in protected secret
79
- storage; do not put them in the repository or a checked-in `.env` file.
80
-
81
- Release the adapter separately when its version changes, update the changelog,
82
- tag the source commit, and publish the checksums and supported-version notes.
83
-
84
- ## Deployment gate
85
-
86
- For a direct RubyDB production deployment, follow [lesson 5](05-rubydb-production-server.md)
87
- from top to bottom before this gate. For a massive Rails application, follow
88
- [lesson 6](06-postgresql-massive-apps.md) and keep RubyDB at a separate service
89
- boundary.
90
-
91
- Do not promote until all of these have an owner and a recorded result:
92
-
93
- * application tests pass against the production database topology;
94
- * migrations pass on empty and populated staging data;
95
- * a verified backup restores on another path or host;
96
- * load tests cover concurrency, timeouts, cancellation, and resource limits;
97
- * multi-process client/server tests cover restart and network failure;
98
- * failover and fencing behavior is validated if high availability is claimed;
99
- * TLS, secrets, least privilege, certificate rotation, and audit logging are
100
- reviewed;
101
- * dashboards and alerts page an on-call person;
102
- * rollback, upgrade, and data-reconciliation procedures are rehearsed; and
103
- * the README and compatibility guide state what is supported and what is not.
104
-
105
- ## A sensible first production architecture
106
-
107
- For a large Rails product, use managed PostgreSQL for the main application and
108
- deploy RubyDB only for an independently owned microservice whose workload has
109
- passed the lessons above. For a small internal or single-owner service, RubyDB
110
- server mode can be reasonable when its SQL, concurrency, recovery, and
111
- operational limits are accepted. Do not call either architecture universally
112
- compatible without workload evidence.
113
-
114
- ## Final checkpoint
115
-
116
- The journey is complete when a new operator can deploy the exact release,
117
- verify a real query, observe health and capacity, restore data, and explain the
118
- rollback path without relying on the author’s laptop. Keep the evidence with
119
- the release and repeat the drills after major RubyDB, Rails, schema, or hosting
120
- changes.
121
-
122
- Continue using the repository’s [CLI guide](../docs/cli.md), [production
123
- operations guide](../docs/operations/production-guide.md), [Rails compatibility
124
- guide](../docs/rails/compatibility-guide.md), and [SQL compatibility
125
- guide](../docs/sql/compatibility-guide.md) as the detailed references.
147
+ The package is a Node.js/TypeScript RubyDB client, not a PostgreSQL driver. Pin
148
+ the npm client and RubyDB server versions together and validate the target
149
+ application's SQL, retry, TLS, migration, backup, and failover behavior.
150
+
151
+ ## Deployment gate
152
+
153
+ For a direct RubyDB production deployment, follow [lesson 5](05-rubydb-production-server.md)
154
+ from top to bottom before this gate. For a massive Rails application, follow
155
+ [lesson 6](06-postgresql-massive-apps.md) and keep RubyDB at a separate service
156
+ boundary.
157
+
158
+ Do not promote until all of these have an owner and a recorded result:
159
+
160
+ * application tests pass against the production database topology;
161
+ * migrations pass on empty and populated staging data;
162
+ * a verified backup restores on another path or host;
163
+ * load tests cover concurrency, timeouts, cancellation, and resource limits;
164
+ * multi-process client/server tests cover restart and network failure;
165
+ * failover and fencing behavior is validated if high availability is claimed;
166
+ * TLS, secrets, least privilege, certificate rotation, and audit logging are
167
+ reviewed;
168
+ * dashboards and alerts page an on-call person;
169
+ * rollback, upgrade, and data-reconciliation procedures are rehearsed; and
170
+ * the README and compatibility guide state what is supported and what is not.
171
+
172
+ ## A sensible first production architecture
173
+
174
+ For a large Rails product, use managed PostgreSQL for the main application and
175
+ deploy RubyDB only for an independently owned microservice whose workload has
176
+ passed the lessons above. For a small internal or single-owner service, RubyDB
177
+ server mode can be reasonable when its SQL, concurrency, recovery, and
178
+ operational limits are accepted. Do not call either architecture universally
179
+ compatible without workload evidence.
180
+
181
+ ## Final checkpoint
182
+
183
+ The journey is complete when a new operator can deploy the exact release,
184
+ verify a real query, observe health and capacity, restore data, and explain the
185
+ rollback path without relying on the author’s laptop. Keep the evidence with
186
+ the release and repeat the drills after major RubyDB, Rails, schema, or hosting
187
+ changes.
188
+
189
+ Continue using the repository’s [CLI guide](../docs/cli.md), [production
190
+ operations guide](../docs/operations/production-guide.md), [Rails compatibility
191
+ guide](../docs/rails/compatibility-guide.md), and [SQL compatibility
192
+ guide](../docs/sql/compatibility-guide.md) as the detailed references.