Skip to content

Commit ed11ad2

Browse files
committed
docs: align use-case claims with the JS port
The fit guide called a rate limiter an anti-pattern while the JS README sold per-key rate limits, and "Is it worth installing here?" listed long-lived workflows with no limit. A reader who compared the two projects got contradictory advice about one runtime. Both now draw one line. A low-rate quota that a reminder refills fits, because each check is one durable ordered message with a retained history row. A limiter that every request touches does not. A workflow fits when one entity owns the mutable state and its mailbox holds the step order; a durable execution engine that replays named steps from a step log is a different tool. Name Solid Objects Pro in the fit guide for the high-QPS cases it rejects, and map its three capabilities onto them. The README already pointed there; the guide stopped at "anti-pattern". Title the README "Solid Objects Ruby" to match "Solid Objects JS" in the Node package, and give both the same two badges: a CI badge pinned to main and a registry version badge. The gem name, the module, and the published metadata do not change.
1 parent 3cf4588 commit ed11ad2

3 files changed

Lines changed: 58 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- Align the use-case claims with solid-objects-js. "Is it worth installing
6+
here?" listed long-lived workflows without a limit, while `docs/fit.md`
7+
called a rate limiter an anti-pattern and the JS README sold per-key rate
8+
limits. Both projects now say the same thing: a low-rate quota that a
9+
reminder refills fits, because each check is one durable ordered message; a
10+
limiter that every request touches does not; and a workflow fits when one
11+
entity owns the mutable state and its mailbox holds the step order. A durable
12+
execution engine that replays named steps from a step log remains a different
13+
tool.
14+
- Name Solid Objects Pro in `docs/fit.md` for the high-QPS cases the guide
15+
rejects, and map its three capabilities onto them: grouped operations,
16+
ephemeral operations, and reactive projections. The README already pointed
17+
there; the fit guide stopped at "anti-pattern".
18+
- Title the README "Solid Objects Ruby", matching "Solid Objects JS" in the
19+
Node package, and give both the same two badges. The CI badge now pins
20+
`?branch=main`, and a RubyGems version badge sits beside it. The gem name,
21+
the module, and the published metadata do not change.
22+
323
## 0.14.2 - 2026-08-25
424

525
- Rewrite the first screen around the objection a reader actually has. The

README.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
# Solid Objects
1+
# Solid Objects Ruby
22

3-
[![CI](https://github.com/cardmagic/solid-objects-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/cardmagic/solid-objects-ruby/actions/workflows/ci.yml)
3+
[![CI](https://github.com/cardmagic/solid-objects-ruby/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/cardmagic/solid-objects-ruby/actions/workflows/ci.yml)
4+
[![gem](https://img.shields.io/gem/v/solid_objects)](https://rubygems.org/gems/solid_objects)
45

56
**Self-hosted, distributed Durable Objects in Rails without a daemon using your existing SQL database.**
67

@@ -137,15 +138,23 @@ If it all happens inside one request, use a lock.
137138
## Is it worth installing here?
138139

139140
Worth it when several requests, jobs, or processes act on the same cart, chat
140-
room, device twin, game room, or long-lived workflow, and each next action
141-
needs the last committed state. Worth it when that same thing also owns work
142-
that fires later, or a number a live page must show.
141+
room, device twin, game room, long-lived workflow, or refillable quota, and
142+
each next action needs the last committed state. Worth it when that same thing
143+
also owns work that fires later, or a number a live page must show.
144+
145+
Two of those have a limit. A workflow fits when one entity owns the mutable
146+
state and its mailbox holds the step order. A durable execution engine that
147+
replays named steps from a step log is a different tool, because Solid Objects
148+
redelivers an ordered message and retries it. A quota fits when one identity
149+
checks it a few times per minute, because each check is one durable ordered
150+
message with a retained history row. A limiter that every request to that
151+
identity touches does not fit here.
143152

144153
Not worth it for a plain counter, a single-row update inside one transaction, a
145154
stateless job, bulk ingestion or a data-parallel pipeline, CPU-heavy work, a
146155
large JSON document that belongs in normalized rows, high-QPS request reads, or
147-
a global rate-limit counter that every request touches. One hot identity is
148-
serialized on purpose, so making everything one identity makes a queue.
156+
a rate-limit counter that every request touches. One hot identity is serialized
157+
on purpose, so making everything one identity makes a queue.
149158

150159
High-QPS reads and hot identities are where this runtime stops being the right
151160
tool on its own. [Solid Objects Pro](https://solidobjects.pro/) is a commercial

docs/fit.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ Solid Objects is a good candidate when most of these are true:
2424
asynchronous features, a Solid Objects runtime process.
2525

2626
Typical fits include checkout state machines, collaborative rooms, device
27-
twins, durable assessments, approval workflows, and user-specific scheduling.
27+
twins, durable assessments, approval workflows, user-specific scheduling, and
28+
low-rate quotas that a reminder refills.
29+
30+
A workflow fits when one entity owns the mutable state and its mailbox holds
31+
the step order. A durable execution engine that replays named steps from a step
32+
log is a different tool: Solid Objects redelivers an ordered message and
33+
retries it, and does not replay a handler from a step log.
2834

2935
## Poor fit and anti-patterns
3036

@@ -46,10 +52,21 @@ when any of these dominate:
4652
- State that is clearer as a normal record with database constraints and direct
4753
service methods.
4854

49-
A rate limiter is usually a poor actor: it is hot, request-critical, and often
50-
expires rather than requiring permanent message history. An impressions
51-
pipeline is also a poor actor: its value is high-throughput append and
52-
aggregation, not serialized mutable state.
55+
A request-path rate limiter is usually a poor actor: it is hot,
56+
request-critical, and often expires rather than requiring permanent message
57+
history. A low-rate quota is the case that does fit, such as five password
58+
resets an hour for one account, where a reminder refills the bucket and each
59+
check is one durable ordered message. An impressions pipeline is also a poor
60+
actor: its value is high-throughput append and aggregation, not serialized
61+
mutable state.
62+
63+
[Solid Objects Pro](https://solidobjects.pro/) is the commercial scaling layer
64+
for the high-QPS cases in this section. Grouped operations coalesce concurrent
65+
calls into one bulk insert. Ephemeral operations hold a loss-tolerant call in
66+
process memory and write no journal row, which is the mode for an abuse limiter,
67+
a presence signal, or a view count. Reactive projections materialize a read
68+
model from the durable broadcast outbox, so request-path reads stop competing
69+
with mailbox work.
5370

5471
## Cost model
5572

0 commit comments

Comments
 (0)