@iann29/rastro 0.1.0-alpha.1 → 0.1.0-alpha.11
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.
- package/README.md +693 -69
- package/agent/integration.md +801 -0
- package/agent/manifest.json +205 -0
- package/agent/manifest.schema.json +444 -0
- package/dist/client/federation.d.ts +381 -0
- package/dist/client/federation.d.ts.map +1 -0
- package/dist/client/federation.js +274 -0
- package/dist/client/federation.js.map +1 -0
- package/dist/client/index.d.ts +2673 -15
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +565 -33
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +22 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +315 -4
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/_generated/server.d.ts +4 -0
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js.map +1 -1
- package/dist/component/affiliates.d.ts.map +1 -1
- package/dist/component/affiliates.js +6 -2
- package/dist/component/affiliates.js.map +1 -1
- package/dist/component/cardinality.d.ts +12 -0
- package/dist/component/cardinality.d.ts.map +1 -0
- package/dist/component/cardinality.js +94 -0
- package/dist/component/cardinality.js.map +1 -0
- package/dist/component/constants.d.ts +28 -1
- package/dist/component/constants.d.ts.map +1 -1
- package/dist/component/constants.js +44 -1
- package/dist/component/constants.js.map +1 -1
- package/dist/component/convex.config.d.ts +6 -1
- package/dist/component/convex.config.js +9 -1
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/coverage.d.ts +27 -0
- package/dist/component/coverage.d.ts.map +1 -0
- package/dist/component/coverage.js +56 -0
- package/dist/component/coverage.js.map +1 -0
- package/dist/component/diagnostics.d.ts +9 -0
- package/dist/component/diagnostics.d.ts.map +1 -0
- package/dist/component/diagnostics.js +47 -0
- package/dist/component/diagnostics.js.map +1 -0
- package/dist/component/errors.d.ts +1 -1
- package/dist/component/errors.d.ts.map +1 -1
- package/dist/component/errors.js.map +1 -1
- package/dist/component/eventStore.d.ts +21 -9
- package/dist/component/eventStore.d.ts.map +1 -1
- package/dist/component/eventStore.js +142 -152
- package/dist/component/eventStore.js.map +1 -1
- package/dist/component/funnels.d.ts.map +1 -1
- package/dist/component/funnels.js +5 -3
- package/dist/component/funnels.js.map +1 -1
- package/dist/component/geo.d.ts +73 -0
- package/dist/component/geo.d.ts.map +1 -0
- package/dist/component/geo.js +648 -0
- package/dist/component/geo.js.map +1 -0
- package/dist/component/goals.d.ts.map +1 -1
- package/dist/component/goals.js +8 -5
- package/dist/component/goals.js.map +1 -1
- package/dist/component/guards.d.ts.map +1 -1
- package/dist/component/guards.js.map +1 -1
- package/dist/component/http.d.ts.map +1 -1
- package/dist/component/http.js +281 -62
- package/dist/component/http.js.map +1 -1
- package/dist/component/identity.d.ts +13 -0
- package/dist/component/identity.d.ts.map +1 -0
- package/dist/component/identity.js +58 -0
- package/dist/component/identity.js.map +1 -0
- package/dist/component/ingest.d.ts +3 -1
- package/dist/component/ingest.d.ts.map +1 -1
- package/dist/component/ingest.js +498 -95
- package/dist/component/ingest.js.map +1 -1
- package/dist/component/live.d.ts.map +1 -1
- package/dist/component/live.js +7 -6
- package/dist/component/live.js.map +1 -1
- package/dist/component/localTime.d.ts +25 -0
- package/dist/component/localTime.d.ts.map +1 -0
- package/dist/component/localTime.js +126 -0
- package/dist/component/localTime.js.map +1 -0
- package/dist/component/reports.d.ts +266 -10
- package/dist/component/reports.d.ts.map +1 -1
- package/dist/component/reports.js +1243 -137
- package/dist/component/reports.js.map +1 -1
- package/dist/component/retention.d.ts +75 -1
- package/dist/component/retention.d.ts.map +1 -1
- package/dist/component/retention.js +561 -38
- package/dist/component/retention.js.map +1 -1
- package/dist/component/rollupStore.d.ts +320 -0
- package/dist/component/rollupStore.d.ts.map +1 -0
- package/dist/component/rollupStore.js +596 -0
- package/dist/component/rollupStore.js.map +1 -0
- package/dist/component/rollups.d.ts +20 -0
- package/dist/component/rollups.d.ts.map +1 -0
- package/dist/component/rollups.js +73 -0
- package/dist/component/rollups.js.map +1 -0
- package/dist/component/sanitize.d.ts +24 -1
- package/dist/component/sanitize.d.ts.map +1 -1
- package/dist/component/sanitize.js +96 -16
- package/dist/component/sanitize.js.map +1 -1
- package/dist/component/schema.d.ts +687 -65
- package/dist/component/schema.js +187 -20
- package/dist/component/schema.js.map +1 -1
- package/dist/component/sites.d.ts +12 -0
- package/dist/component/sites.d.ts.map +1 -1
- package/dist/component/sites.js +41 -7
- package/dist/component/sites.js.map +1 -1
- package/dist/component/useragent.d.ts +9 -0
- package/dist/component/useragent.d.ts.map +1 -0
- package/dist/component/useragent.js +152 -0
- package/dist/component/useragent.js.map +1 -0
- package/dist/component/validators.d.ts +124 -69
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +35 -14
- package/dist/component/validators.js.map +1 -1
- package/dist/component/visitors.d.ts +19 -0
- package/dist/component/visitors.d.ts.map +1 -0
- package/dist/component/visitors.js +86 -0
- package/dist/component/visitors.js.map +1 -0
- package/dist/component/vitals.d.ts +41 -0
- package/dist/component/vitals.d.ts.map +1 -0
- package/dist/component/vitals.js +115 -0
- package/dist/component/vitals.js.map +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/tracker/generated.d.ts +11 -4
- package/dist/tracker/generated.d.ts.map +1 -1
- package/dist/tracker/generated.js +11 -4
- package/dist/tracker/generated.js.map +1 -1
- package/dist/tracker/tracker.d.ts +1 -1
- package/dist/tracker/tracker.d.ts.map +1 -1
- package/dist/tracker/tracker.js +57 -20
- package/dist/tracker/tracker.js.map +1 -1
- package/dist/tracker/vitals.d.ts +10 -0
- package/dist/tracker/vitals.d.ts.map +1 -0
- package/dist/tracker/vitals.js +140 -0
- package/dist/tracker/vitals.js.map +1 -0
- package/dist/tracker.min.js +1 -1
- package/dist/vitals.min.js +1 -0
- package/docs/benchmarks/2026-08-20-realistic.md +76 -76
- package/docs/benchmarks/2026-08-21-formal-certification.md +353 -0
- package/docs/benchmarks/2026-08-30-alpha6-recertification.md +206 -0
- package/docs/federation-setup.md +464 -0
- package/docs/federation.md +352 -0
- package/docs/upgrading.md +344 -0
- package/llms.txt +72 -0
- package/package.json +55 -11
- package/scripts/benchmark-ingest.mjs +175 -73
- package/scripts/generate-federation-keys.mjs +20 -0
- package/src/component/_generated/api.ts +22 -0
- package/src/component/_generated/component.ts +381 -4
- package/src/component/_generated/server.ts +4 -0
- package/src/component/affiliates.ts +20 -5
- package/src/component/cardinality.ts +117 -0
- package/src/component/constants.ts +44 -1
- package/src/component/convex.config.ts +11 -1
- package/src/component/coverage.ts +71 -0
- package/src/component/diagnostics.ts +65 -0
- package/src/component/errors.ts +2 -1
- package/src/component/eventStore.ts +217 -193
- package/src/component/funnels.ts +19 -16
- package/src/component/geo.ts +835 -0
- package/src/component/goals.ts +29 -21
- package/src/component/guards.ts +3 -1
- package/src/component/http.ts +404 -70
- package/src/component/identity.ts +74 -0
- package/src/component/ingest.ts +894 -188
- package/src/component/live.ts +13 -7
- package/src/component/localTime.ts +167 -0
- package/src/component/reports.ts +1872 -197
- package/src/component/retention.ts +788 -96
- package/src/component/rollupStore.ts +799 -0
- package/src/component/rollups.ts +82 -0
- package/src/component/sanitize.ts +144 -29
- package/src/component/schema.ts +217 -21
- package/src/component/sites.ts +59 -12
- package/src/component/useragent.ts +171 -0
- package/src/component/validators.ts +49 -14
- package/src/component/visitors.ts +116 -0
- package/src/component/vitals.ts +146 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# Formal ingest certification, 2026-08-21
|
|
2
|
+
|
|
3
|
+
This report preserves four isolated ten-minute benchmark runs against the
|
|
4
|
+
non-production Synapse canary. It is engineering evidence for the tested commit
|
|
5
|
+
and deployment, not a production SLA.
|
|
6
|
+
|
|
7
|
+
## Environment
|
|
8
|
+
|
|
9
|
+
| Item | Value |
|
|
10
|
+
| ------------------- | -------------------------------------------------- |
|
|
11
|
+
| Git commit | `e6ae92658c86c1931e697fa2a38c80fd902f7afa` |
|
|
12
|
+
| Package version | `0.1.0-alpha.3` |
|
|
13
|
+
| Deployment | DEV `fast-finch-7454` |
|
|
14
|
+
| Benchmark site | `kx75pnr9wap522n0zmh4nnb4jh8cv110` |
|
|
15
|
+
| Driver | One local Node.js process |
|
|
16
|
+
| Reconciliation | Exact run-scoped session IDs, indexed pages of 100 |
|
|
17
|
+
| Health before/after | `ok: true` |
|
|
18
|
+
| GeoIP provider | Disabled |
|
|
19
|
+
|
|
20
|
+
All runs used `--duration 600 --certify`. Runs were sequential so the profiles
|
|
21
|
+
did not compete with each other. A harness certification means the run lasted
|
|
22
|
+
the required duration, had clean request accounting, and reconciled every
|
|
23
|
+
expected stored event. Meeting the separate 100 million stored-events/day target
|
|
24
|
+
requires at least 1,157.41 stored events/second.
|
|
25
|
+
|
|
26
|
+
## Results
|
|
27
|
+
|
|
28
|
+
| Profile | Concurrency | Batch | Accepted | Stored | Stored/s | Certified stored/day | p95 | Exact reconciliation | 100M/day target |
|
|
29
|
+
| --------- | ----------: | ----: | -------: | ------: | -------: | -------------------: | -------: | -------------------- | ---------------- |
|
|
30
|
+
| Lean | 100 | 50 | 952,600 | 952,600 | 1,582 | 136,654,617 | 4,543 ms | 952,600 / 952,600 | Pass |
|
|
31
|
+
| Realistic | 75 | 50 | 885,700 | 842,080 | 1,398 | 120,808,947 | 4,247 ms | 842,080 / 842,080 | Pass |
|
|
32
|
+
| Heavy | 100 | 20 | 353,980 | 353,980 | 588 | 50,769,480 | 5,787 ms | 353,980 / 353,980 | **Below target** |
|
|
33
|
+
| Feature | 100 | 15 | 232,170 | 232,170 | 384 | 33,218,356 | 6,226 ms | 232,170 / 232,170 | **Below target** |
|
|
34
|
+
|
|
35
|
+
The realistic run accepted 43,620 heartbeats, which intentionally update live
|
|
36
|
+
presence without increasing persistent event counts. Its accepted-versus-stored
|
|
37
|
+
difference is therefore exact. The heavy request measured 62,054 bytes and
|
|
38
|
+
sustained 1,828,443 request bytes/second below the 64 KiB HTTP body limit.
|
|
39
|
+
|
|
40
|
+
## Heavy recertification after byte-accounting optimization
|
|
41
|
+
|
|
42
|
+
Commit `4460ad34314a6e15c24a0c78aab6e6ce85db5c60` reused each event's exact
|
|
43
|
+
UTF-8 byte measurement for both batch validation and rate limits, removing one
|
|
44
|
+
full-payload serialization from the ingestion transaction. A new isolated
|
|
45
|
+
ten-minute run on 2026-08-22 used the same deployment, site, concurrency, batch
|
|
46
|
+
size, and heavy payload.
|
|
47
|
+
|
|
48
|
+
| Result | Original | Recertified | Change |
|
|
49
|
+
| -------------------- | ---------: | ----------: | -----: |
|
|
50
|
+
| Stored events/s | 588 | 887 | +50.9% |
|
|
51
|
+
| Certified stored/day | 50,769,480 | 76,623,702 | +50.9% |
|
|
52
|
+
| Request bytes/s | 1,828,443 | 2,759,875 | +50.9% |
|
|
53
|
+
| p95 latency | 5,787 ms | 3,670 ms | -36.6% |
|
|
54
|
+
|
|
55
|
+
The recertification remained below the separate 100 million events/day target,
|
|
56
|
+
but raised the measured heavy-payload ceiling without changing payload shape or
|
|
57
|
+
weakening validation, rate limits, or reconciliation.
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"label": "heavy-2026-08-22T04:03:22.517Z",
|
|
62
|
+
"runId": "f3943151-bc71-4806-b609-69faf8bdfb0c",
|
|
63
|
+
"profile": "heavy",
|
|
64
|
+
"targetDurationSeconds": 600,
|
|
65
|
+
"elapsedMs": 601726,
|
|
66
|
+
"terminationReason": "duration",
|
|
67
|
+
"durationCompleted": true,
|
|
68
|
+
"certification": {
|
|
69
|
+
"requested": true,
|
|
70
|
+
"passed": true,
|
|
71
|
+
"minimumDurationSeconds": 600
|
|
72
|
+
},
|
|
73
|
+
"concurrency": 100,
|
|
74
|
+
"batchSize": 20,
|
|
75
|
+
"sessionPool": 2048,
|
|
76
|
+
"maximumRequests": null,
|
|
77
|
+
"requests": { "started": 26682, "completed": 26682, "failures": 0 },
|
|
78
|
+
"events": {
|
|
79
|
+
"sent": 533640,
|
|
80
|
+
"heartbeats": 0,
|
|
81
|
+
"accepted": 533640,
|
|
82
|
+
"stored": 533640,
|
|
83
|
+
"duplicates": 0,
|
|
84
|
+
"rejected": 0,
|
|
85
|
+
"failed": 0
|
|
86
|
+
},
|
|
87
|
+
"errors": {},
|
|
88
|
+
"throughput": {
|
|
89
|
+
"eventsPerSecond": 887,
|
|
90
|
+
"storedEventsPerSecond": 887,
|
|
91
|
+
"estimatedEventsPerDay": 76623702,
|
|
92
|
+
"estimatedStoredEventsPerDay": 76623702,
|
|
93
|
+
"certifiedEventsPerDay": 76623702,
|
|
94
|
+
"certifiedStoredEventsPerDay": 76623702,
|
|
95
|
+
"requestBytesPerSecond": 2759875
|
|
96
|
+
},
|
|
97
|
+
"latencyMs": { "p50": 2035, "p95": 3670, "p99": 4755, "max": 8139 },
|
|
98
|
+
"reconciliation": {
|
|
99
|
+
"scope": "run-session-ids",
|
|
100
|
+
"reliable": true,
|
|
101
|
+
"expectedSessions": 2048,
|
|
102
|
+
"requestedSessions": 2048,
|
|
103
|
+
"foundSessions": 2048,
|
|
104
|
+
"acceptedEvents": 533640,
|
|
105
|
+
"acceptedHeartbeats": 0,
|
|
106
|
+
"expectedStoredEvents": 533640,
|
|
107
|
+
"storedEvents": 533640,
|
|
108
|
+
"matches": true
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Run artifacts
|
|
114
|
+
|
|
115
|
+
### Lean
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"label": "lean-2026-08-21T13:31:27.434Z",
|
|
120
|
+
"runId": "41788de1-964e-4315-8b00-f295e202f2e0",
|
|
121
|
+
"profile": "lean",
|
|
122
|
+
"targetDurationSeconds": 600,
|
|
123
|
+
"elapsedMs": 602282,
|
|
124
|
+
"terminationReason": "duration",
|
|
125
|
+
"durationCompleted": true,
|
|
126
|
+
"certification": {
|
|
127
|
+
"requested": true,
|
|
128
|
+
"passed": true,
|
|
129
|
+
"minimumDurationSeconds": 600
|
|
130
|
+
},
|
|
131
|
+
"concurrency": 100,
|
|
132
|
+
"batchSize": 50,
|
|
133
|
+
"sessionPool": "unique-per-request",
|
|
134
|
+
"maximumRequests": null,
|
|
135
|
+
"requests": { "started": 19052, "completed": 19052, "failures": 0 },
|
|
136
|
+
"events": {
|
|
137
|
+
"sent": 952600,
|
|
138
|
+
"heartbeats": 0,
|
|
139
|
+
"accepted": 952600,
|
|
140
|
+
"stored": 952600,
|
|
141
|
+
"duplicates": 0,
|
|
142
|
+
"rejected": 0,
|
|
143
|
+
"failed": 0
|
|
144
|
+
},
|
|
145
|
+
"errors": {},
|
|
146
|
+
"throughput": {
|
|
147
|
+
"eventsPerSecond": 1582,
|
|
148
|
+
"storedEventsPerSecond": 1582,
|
|
149
|
+
"estimatedEventsPerDay": 136654617,
|
|
150
|
+
"estimatedStoredEventsPerDay": 136654617,
|
|
151
|
+
"certifiedEventsPerDay": 136654617,
|
|
152
|
+
"certifiedStoredEventsPerDay": 136654617,
|
|
153
|
+
"requestBytesPerSecond": 438830
|
|
154
|
+
},
|
|
155
|
+
"latencyMs": { "p50": 2979, "p95": 4543, "p99": 5217, "max": 5628 },
|
|
156
|
+
"reconciliation": {
|
|
157
|
+
"scope": "run-session-ids",
|
|
158
|
+
"reliable": true,
|
|
159
|
+
"expectedSessions": 19052,
|
|
160
|
+
"requestedSessions": 19052,
|
|
161
|
+
"foundSessions": 19052,
|
|
162
|
+
"acceptedEvents": 952600,
|
|
163
|
+
"acceptedHeartbeats": 0,
|
|
164
|
+
"expectedStoredEvents": 952600,
|
|
165
|
+
"storedEvents": 952600,
|
|
166
|
+
"matches": true
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Realistic
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"label": "realistic-2026-08-21T13:42:07.118Z",
|
|
176
|
+
"runId": "8a883d9a-537a-4ce5-b300-be77995ba5da",
|
|
177
|
+
"profile": "realistic",
|
|
178
|
+
"targetDurationSeconds": 600,
|
|
179
|
+
"elapsedMs": 602238,
|
|
180
|
+
"terminationReason": "duration",
|
|
181
|
+
"durationCompleted": true,
|
|
182
|
+
"certification": {
|
|
183
|
+
"requested": true,
|
|
184
|
+
"passed": true,
|
|
185
|
+
"minimumDurationSeconds": 600
|
|
186
|
+
},
|
|
187
|
+
"concurrency": 75,
|
|
188
|
+
"batchSize": 50,
|
|
189
|
+
"sessionPool": 2048,
|
|
190
|
+
"maximumRequests": null,
|
|
191
|
+
"requests": { "started": 17714, "completed": 17714, "failures": 0 },
|
|
192
|
+
"events": {
|
|
193
|
+
"sent": 885700,
|
|
194
|
+
"heartbeats": 43620,
|
|
195
|
+
"accepted": 885700,
|
|
196
|
+
"stored": 842080,
|
|
197
|
+
"duplicates": 0,
|
|
198
|
+
"rejected": 0,
|
|
199
|
+
"failed": 0
|
|
200
|
+
},
|
|
201
|
+
"errors": {},
|
|
202
|
+
"throughput": {
|
|
203
|
+
"eventsPerSecond": 1471,
|
|
204
|
+
"storedEventsPerSecond": 1398,
|
|
205
|
+
"estimatedEventsPerDay": 127066887,
|
|
206
|
+
"estimatedStoredEventsPerDay": 120808947,
|
|
207
|
+
"certifiedEventsPerDay": 127066887,
|
|
208
|
+
"certifiedStoredEventsPerDay": 120808947,
|
|
209
|
+
"requestBytesPerSecond": 445267
|
|
210
|
+
},
|
|
211
|
+
"latencyMs": { "p50": 2257, "p95": 4247, "p99": 5122, "max": 6133 },
|
|
212
|
+
"reconciliation": {
|
|
213
|
+
"scope": "run-session-ids",
|
|
214
|
+
"reliable": true,
|
|
215
|
+
"expectedSessions": 2048,
|
|
216
|
+
"requestedSessions": 2048,
|
|
217
|
+
"foundSessions": 2048,
|
|
218
|
+
"acceptedEvents": 885700,
|
|
219
|
+
"acceptedHeartbeats": 43620,
|
|
220
|
+
"expectedStoredEvents": 842080,
|
|
221
|
+
"storedEvents": 842080,
|
|
222
|
+
"matches": true
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Heavy
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"label": "heavy-2026-08-21T13:52:43.382Z",
|
|
232
|
+
"runId": "8cd7221e-2e33-4e94-9f9d-13bb4a84c60e",
|
|
233
|
+
"profile": "heavy",
|
|
234
|
+
"targetDurationSeconds": 600,
|
|
235
|
+
"elapsedMs": 602407,
|
|
236
|
+
"terminationReason": "duration",
|
|
237
|
+
"durationCompleted": true,
|
|
238
|
+
"certification": {
|
|
239
|
+
"requested": true,
|
|
240
|
+
"passed": true,
|
|
241
|
+
"minimumDurationSeconds": 600
|
|
242
|
+
},
|
|
243
|
+
"concurrency": 100,
|
|
244
|
+
"batchSize": 20,
|
|
245
|
+
"sessionPool": 2048,
|
|
246
|
+
"maximumRequests": null,
|
|
247
|
+
"requests": { "started": 17699, "completed": 17699, "failures": 0 },
|
|
248
|
+
"events": {
|
|
249
|
+
"sent": 353980,
|
|
250
|
+
"heartbeats": 0,
|
|
251
|
+
"accepted": 353980,
|
|
252
|
+
"stored": 353980,
|
|
253
|
+
"duplicates": 0,
|
|
254
|
+
"rejected": 0,
|
|
255
|
+
"failed": 0
|
|
256
|
+
},
|
|
257
|
+
"errors": {},
|
|
258
|
+
"throughput": {
|
|
259
|
+
"eventsPerSecond": 588,
|
|
260
|
+
"storedEventsPerSecond": 588,
|
|
261
|
+
"estimatedEventsPerDay": 50769480,
|
|
262
|
+
"estimatedStoredEventsPerDay": 50769480,
|
|
263
|
+
"certifiedEventsPerDay": 50769480,
|
|
264
|
+
"certifiedStoredEventsPerDay": 50769480,
|
|
265
|
+
"requestBytesPerSecond": 1828443
|
|
266
|
+
},
|
|
267
|
+
"latencyMs": { "p50": 2968, "p95": 5787, "p99": 6942, "max": 7839 },
|
|
268
|
+
"reconciliation": {
|
|
269
|
+
"scope": "run-session-ids",
|
|
270
|
+
"reliable": true,
|
|
271
|
+
"expectedSessions": 2048,
|
|
272
|
+
"requestedSessions": 2048,
|
|
273
|
+
"foundSessions": 2048,
|
|
274
|
+
"acceptedEvents": 353980,
|
|
275
|
+
"acceptedHeartbeats": 0,
|
|
276
|
+
"expectedStoredEvents": 353980,
|
|
277
|
+
"storedEvents": 353980,
|
|
278
|
+
"matches": true
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Feature
|
|
284
|
+
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"label": "feature-2026-08-21T14:03:20.654Z",
|
|
288
|
+
"runId": "8e60bc5f-6fff-4791-b02c-0e7340767b55",
|
|
289
|
+
"profile": "feature",
|
|
290
|
+
"targetDurationSeconds": 600,
|
|
291
|
+
"elapsedMs": 603868,
|
|
292
|
+
"terminationReason": "duration",
|
|
293
|
+
"durationCompleted": true,
|
|
294
|
+
"certification": {
|
|
295
|
+
"requested": true,
|
|
296
|
+
"passed": true,
|
|
297
|
+
"minimumDurationSeconds": 600
|
|
298
|
+
},
|
|
299
|
+
"concurrency": 100,
|
|
300
|
+
"batchSize": 15,
|
|
301
|
+
"sessionPool": 2048,
|
|
302
|
+
"maximumRequests": null,
|
|
303
|
+
"requests": { "started": 15478, "completed": 15478, "failures": 0 },
|
|
304
|
+
"events": {
|
|
305
|
+
"sent": 232170,
|
|
306
|
+
"heartbeats": 0,
|
|
307
|
+
"accepted": 232170,
|
|
308
|
+
"stored": 232170,
|
|
309
|
+
"duplicates": 0,
|
|
310
|
+
"rejected": 0,
|
|
311
|
+
"failed": 0
|
|
312
|
+
},
|
|
313
|
+
"errors": {},
|
|
314
|
+
"throughput": {
|
|
315
|
+
"eventsPerSecond": 384,
|
|
316
|
+
"storedEventsPerSecond": 384,
|
|
317
|
+
"estimatedEventsPerDay": 33218356,
|
|
318
|
+
"estimatedStoredEventsPerDay": 33218356,
|
|
319
|
+
"certifiedEventsPerDay": 33218356,
|
|
320
|
+
"certifiedStoredEventsPerDay": 33218356,
|
|
321
|
+
"requestBytesPerSecond": 119846
|
|
322
|
+
},
|
|
323
|
+
"latencyMs": { "p50": 3523, "p95": 6226, "p99": 7722, "max": 8524 },
|
|
324
|
+
"reconciliation": {
|
|
325
|
+
"scope": "run-session-ids",
|
|
326
|
+
"reliable": true,
|
|
327
|
+
"expectedSessions": 2048,
|
|
328
|
+
"requestedSessions": 2048,
|
|
329
|
+
"foundSessions": 2048,
|
|
330
|
+
"acceptedEvents": 232170,
|
|
331
|
+
"acceptedHeartbeats": 0,
|
|
332
|
+
"expectedStoredEvents": 232170,
|
|
333
|
+
"storedEvents": 232170,
|
|
334
|
+
"matches": true
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Conclusions
|
|
340
|
+
|
|
341
|
+
- Lean and realistic traffic exceeded 100 million stored events/day for a full
|
|
342
|
+
ten minutes with exact reconciliation and no failures.
|
|
343
|
+
- Heavy and feature traffic completed cleanly but did not meet the 100 million
|
|
344
|
+
stored-events/day target at the tested payloads and concurrency. The latest
|
|
345
|
+
heavy ceiling is 76.62 million events/day after recertification.
|
|
346
|
+
- The updated heavy result demonstrates a different ceiling: 2.76 MB/s of
|
|
347
|
+
near-limit requests. It must not be generalized to minimal or realistic
|
|
348
|
+
payloads.
|
|
349
|
+
- Trusted financial conversions were not exercised. They require a separate
|
|
350
|
+
server-side driver because browser traffic cannot cross the financial trust
|
|
351
|
+
boundary.
|
|
352
|
+
- GeoIP provider behavior was not benchmarked because provider enrichment was
|
|
353
|
+
disabled on this deployment.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Ingest recertification, 2026-08-30
|
|
2
|
+
|
|
3
|
+
This report recertifies the four workload profiles ahead of `0.1.0-alpha.6`,
|
|
4
|
+
against the same deployment and benchmark site as the
|
|
5
|
+
[2026-08-21 formal certification](2026-08-21-formal-certification.md). It is
|
|
6
|
+
engineering evidence for the tested revisions and deployment state, not a
|
|
7
|
+
production SLA.
|
|
8
|
+
|
|
9
|
+
## Environment
|
|
10
|
+
|
|
11
|
+
| Item | Value |
|
|
12
|
+
| ------------------- | ---------------------------------------------------------------- |
|
|
13
|
+
| Deployment | DEV canary `fast-finch-7454` (unchanged since 2026-08-21) |
|
|
14
|
+
| Benchmark site | `kx75pnr9wap522n0zmh4nnb4jh8cv110` (unchanged) |
|
|
15
|
+
| Lean run revision | `ba9eff1` (main before Web Vitals) |
|
|
16
|
+
| Later run revisions | Web Vitals build; component sources identical to merge `6250526` |
|
|
17
|
+
| Driver | One local Node.js process |
|
|
18
|
+
| Reconciliation | Exact run-scoped session IDs, indexed pages of 100 |
|
|
19
|
+
| GeoIP provider | Disabled |
|
|
20
|
+
| Health before runs | `ok: true` |
|
|
21
|
+
|
|
22
|
+
Since the 2026-08-21 certification the wire path gained salted daily visitor
|
|
23
|
+
keys, User-Agent bot rejection, client-hint browser detection, the federation
|
|
24
|
+
hardening, and the `vital` ingest branch (present but idle: no profile sends
|
|
25
|
+
vitals). Unlike 2026-08-21, the canary was not fresh: it accumulated the
|
|
26
|
+
battery's own multi-million-event history while the profiles ran, which is the
|
|
27
|
+
honest way most deployments look after a real day.
|
|
28
|
+
|
|
29
|
+
All certified runs used `--duration 600 --certify`, ran sequentially with at
|
|
30
|
+
least five minutes of cooldown, and had no competing local load. Two runs were
|
|
31
|
+
discarded and repeated because the local DNS resolver failed their first
|
|
32
|
+
connection wave (a client-side condition — the deployment was idle and healthy
|
|
33
|
+
each time); one more was discarded after a mid-run deploy from this same
|
|
34
|
+
machine. Discarded runs are not reported as capacity.
|
|
35
|
+
|
|
36
|
+
## Results
|
|
37
|
+
|
|
38
|
+
Meeting the 100 million stored-events/day target requires at least 1,157.41
|
|
39
|
+
stored events/second.
|
|
40
|
+
|
|
41
|
+
| Profile | Concurrency | Batch | Sessions | Accepted | Stored | Stored/s | Certified stored/day | p95 | Exact reconciliation | 100M/day target |
|
|
42
|
+
| --------- | ----------: | ----: | -------: | --------: | --------: | -------: | -------------------: | -------: | --------------------- | ---------------- |
|
|
43
|
+
| Lean | 100 | 50 | unique | 1,247,000 | 1,247,000 | 2,071 | 178,948,552 | 4,167 ms | 1,247,000 / 1,247,000 | Pass |
|
|
44
|
+
| Realistic | 75 | 50 | 4,096 | 1,039,050 | 988,995 | 1,644 | 142,036,529 | 4,953 ms | 988,995 / 988,995 | Pass |
|
|
45
|
+
| Heavy | 100 | 20 | 2,048 | 388,040 | 388,040 | 640 | 55,259,642 | 7,702 ms | 388,040 / 388,040 | **Below target** |
|
|
46
|
+
| Feature | 100 | 15 | 2,048 | — | — | — | **failed** | — | — | **Failed** |
|
|
47
|
+
|
|
48
|
+
### Lean
|
|
49
|
+
|
|
50
|
+
Certified by the harness: 24,940 requests, zero failures, duplicates, or
|
|
51
|
+
rejections; exact reconciliation. 178.95M stored events/day is 31% above the
|
|
52
|
+
2026-08-21 result (136.65M) on the same deployment — the byte-measurement reuse
|
|
53
|
+
first recertified for heavy on 2026-08-22 now shows up across the board, and the
|
|
54
|
+
new per-request work (bot check, client hints, salted visitor keys) did not cost
|
|
55
|
+
the hot path its headroom.
|
|
56
|
+
|
|
57
|
+
### Realistic
|
|
58
|
+
|
|
59
|
+
The driver's session pool was doubled to 4,096 (default 2,048) and that change
|
|
60
|
+
is part of this row's workload definition. At the current deployment speed the
|
|
61
|
+
2,048-session pool drives individual sessions past the documented 120
|
|
62
|
+
events/session/minute ingest budget, so a prior attempt lost 2 of 20,477
|
|
63
|
+
requests to `429 RATE_LIMITED` — the limiter working as documented, but not a
|
|
64
|
+
clean certification. With 4,096 sessions the run completed 20,781 requests with
|
|
65
|
+
**zero failures** of any kind.
|
|
66
|
+
|
|
67
|
+
The harness itself did not stamp this run: after the clean 600 s window, its
|
|
68
|
+
first reconciliation query lost a fetch to the local resolver
|
|
69
|
+
(`reconciliation:fetch failed`) and gave up. Reconciliation was re-run
|
|
70
|
+
immediately afterwards with the same `benchmark:reconcileSessionsPage` pages the
|
|
71
|
+
harness uses, with per-page retries:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"runId": "3c81abe6-60cd-4b40-828f-cedf03fedd39",
|
|
76
|
+
"requested": 4096,
|
|
77
|
+
"found": 4096,
|
|
78
|
+
"stored": 988995,
|
|
79
|
+
"expectedStored": 988995
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
988,995 expected stored events (1,039,050 accepted − 50,055 heartbeats), 988,995
|
|
84
|
+
found — exact. 988,995 stored over the 601.6 s window is 1,644 stored/s, 142.04M
|
|
85
|
+
stored events/day, 17.6% above the 2026-08-21 result (120.81M).
|
|
86
|
+
|
|
87
|
+
### Heavy
|
|
88
|
+
|
|
89
|
+
Certified by the harness: 19,402 requests, zero failures, exact reconciliation,
|
|
90
|
+
1,990,190 request bytes/second under the 64 KiB body limit. 55.26M stored
|
|
91
|
+
events/day is 28% below the 2026-08-22 fresh-store recertification (76.62M). The
|
|
92
|
+
payload and validation are unchanged; the store was not. This run followed hours
|
|
93
|
+
of sustained battery load on a canary holding millions of freshly written rows,
|
|
94
|
+
where 2026-08-22 hit a much lighter store. Both numbers stand side by side:
|
|
95
|
+
76.62M remains the fresh-store ceiling, 55.26M is the same workload on a loaded
|
|
96
|
+
store. Neither is overwritten by the other without a matched-state rerun.
|
|
97
|
+
|
|
98
|
+
### Feature — certification FAILED (reproducible defect)
|
|
99
|
+
|
|
100
|
+
The feature profile (goals, funnels, and affiliate attribution all matching)
|
|
101
|
+
cannot currently be certified: a steady ~4–5% of requests fail with
|
|
102
|
+
`500 INTERNAL_ERROR` at every concurrency tried (100, 15, and 5), and each
|
|
103
|
+
failed request loses its whole batch — reconciliation of a 60 s smoke found only
|
|
104
|
+
946 of 997 run sessions, so this is data loss under load. Backend logs show OCC
|
|
105
|
+
retry exhaustion on the affiliate daily rollups, always on the same two
|
|
106
|
+
documents — the two `REPORT_ROLLUP_SHARDS` rows for the demo affiliate's day:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
[CONVEX M(ingest:ingestBatch)] Documents read from or written to the
|
|
110
|
+
"affiliateDailyRollups" table changed while this mutation was being run and on
|
|
111
|
+
every subsequent retry. Another call to this mutation changed the document
|
|
112
|
+
with ID "mh735zse9410dt27ftc8t3tv4s8deazf".
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The defect postdates alpha.3 (the 2026-08-21 feature run predates the
|
|
116
|
+
generation-1 daily rollups and passed clean at 384 stored/s) and predates the
|
|
117
|
+
Web Vitals change, whose fold path is separate. It is tracked as
|
|
118
|
+
[issue #52](https://github.com/amageweb/amage-rastro/issues/52); the fix needs
|
|
119
|
+
wider rollup sharding, rebalanced feature-report read budgets, and a
|
|
120
|
+
rollout-generation bump. Until it lands, no feature-profile capacity is claimed
|
|
121
|
+
at all — the 2026-08-21 33.22M row is historical evidence for alpha.3 only.
|
|
122
|
+
|
|
123
|
+
## Certified run JSON
|
|
124
|
+
|
|
125
|
+
### Lean (`cert-lean-alpha5`, run `862673e3-ff44-492e-a078-5d8c33f70101`)
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"requests": { "started": 24940, "completed": 24940, "failures": 0 },
|
|
130
|
+
"events": {
|
|
131
|
+
"sent": 1247000,
|
|
132
|
+
"heartbeats": 0,
|
|
133
|
+
"accepted": 1247000,
|
|
134
|
+
"stored": 1247000,
|
|
135
|
+
"duplicates": 0,
|
|
136
|
+
"rejected": 0,
|
|
137
|
+
"failed": 0
|
|
138
|
+
},
|
|
139
|
+
"throughput": {
|
|
140
|
+
"storedEventsPerSecond": 2071,
|
|
141
|
+
"certifiedStoredEventsPerDay": 178948552,
|
|
142
|
+
"requestBytesPerSecond": 575501
|
|
143
|
+
},
|
|
144
|
+
"latencyMs": { "p50": 2156, "p95": 4167, "p99": 5925, "max": 7189 },
|
|
145
|
+
"reconciliation": {
|
|
146
|
+
"expectedStoredEvents": 1247000,
|
|
147
|
+
"storedEvents": 1247000,
|
|
148
|
+
"matches": true
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Heavy (`cert-heavy-alpha5-r2`)
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"requests": { "started": 19402, "completed": 19402, "failures": 0 },
|
|
158
|
+
"events": {
|
|
159
|
+
"sent": 388040,
|
|
160
|
+
"accepted": 388040,
|
|
161
|
+
"stored": 388040,
|
|
162
|
+
"duplicates": 0,
|
|
163
|
+
"rejected": 0,
|
|
164
|
+
"failed": 0
|
|
165
|
+
},
|
|
166
|
+
"throughput": {
|
|
167
|
+
"storedEventsPerSecond": 640,
|
|
168
|
+
"certifiedStoredEventsPerDay": 55259642,
|
|
169
|
+
"requestBytesPerSecond": 1990190
|
|
170
|
+
},
|
|
171
|
+
"latencyMs": { "p50": 2545, "p95": 7702, "p99": 10325, "max": 11220 },
|
|
172
|
+
"reconciliation": {
|
|
173
|
+
"expectedStoredEvents": 388040,
|
|
174
|
+
"storedEvents": 388040,
|
|
175
|
+
"matches": true
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Realistic (`cert-realistic-alpha5-r3-a1`, run `3c81abe6-60cd-4b40-828f-cedf03fedd39`)
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"requests": { "started": 20781, "completed": 20781, "failures": 0 },
|
|
185
|
+
"events": {
|
|
186
|
+
"sent": 1039050,
|
|
187
|
+
"heartbeats": 50055,
|
|
188
|
+
"accepted": 1039050,
|
|
189
|
+
"duplicates": 0,
|
|
190
|
+
"rejected": 0,
|
|
191
|
+
"failed": 0
|
|
192
|
+
},
|
|
193
|
+
"throughput": {
|
|
194
|
+
"eventsPerSecond": 1727,
|
|
195
|
+
"requestBytesPerSecond": 523501
|
|
196
|
+
},
|
|
197
|
+
"latencyMs": { "p50": 1790, "p95": 4953, "p99": 7096, "max": 9274 },
|
|
198
|
+
"reconciliation": "lost to a client-side DNS failure; re-run exactly, see above"
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## What still lacks certification
|
|
203
|
+
|
|
204
|
+
GeoIP with a provider enabled, trusted server-side conversions, vitals-bearing
|
|
205
|
+
traffic (the `vital` ingest branch ran idle here), and the feature profile until
|
|
206
|
+
issue #52 is fixed.
|