prefect server in zig
1# configuration audit
2
3comparison of magic values in zig implementation vs python prefect server settings.
4
5**status**: most high-priority items addressed, remaining items are medium/low priority
6
7## http server
8
9| setting | zig value | python default | python env var | notes |
10|---------|-----------|----------------|----------------|-------|
11| port | 4200 | 4200 | `PREFECT_SERVER_API_PORT` | ✅ matches |
12| host | 127.0.0.1 | 127.0.0.1 | `PREFECT_SERVER_API_HOST` | ✅ matches |
13| workers | 1 | 1 | `--workers` CLI flag | ✅ matches |
14| threads | 4 | n/a | - | zap/facil.io specific; python uses async |
15| max_clients | 1000 | n/a | - | zap/facil.io specific; uvicorn unlimited |
16| max_body_size | 16MB | n/a | - | uvicorn default is unlimited |
17| keepalive_timeout | n/a | 5s | `PREFECT_SERVER_API_KEEPALIVE_TIMEOUT` | not implemented in zig |
18
19### notes
20
21- **threads/workers**: zap's model is different (threads per worker). 4 threads × 1 worker is reasonable for single-process mode
22- **max_body_size**: 16MB is reasonable; python has no limit which could be a DoS vector
23
24## api behavior
25
26| setting | zig value | python default | python env var | notes |
27|---------|-----------|----------------|----------------|-------|
28| default_limit | 200 | 200 | `PREFECT_SERVER_API_DEFAULT_LIMIT` | ✅ matches (all endpoints) |
29
30## database
31
32| setting | zig value | python default | python env var | notes |
33|---------|-----------|----------------|----------------|-------|
34| pool_size | 5 | 5 | `PREFECT_SERVER_DATABASE_SQLALCHEMY_POOL_SIZE` | ✅ matches |
35| max_overflow | n/a | 10 | `PREFECT_SERVER_DATABASE_SQLALCHEMY_MAX_OVERFLOW` | not applicable to pg.zig |
36| pool_recycle | n/a | 3600s | - | not implemented |
37| statement_timeout | n/a | 10s | `PREFECT_SERVER_DATABASE_TIMEOUT` | not implemented |
38| connection_timeout | n/a | 5s | `PREFECT_SERVER_DATABASE_CONNECTION_TIMEOUT` | not implemented |
39
40## events
41
42| setting | zig value | python default | python env var | notes |
43|---------|-----------|----------------|----------------|-------|
44| max_event_size | n/a | 1.5MB | `PREFECT_SERVER_EVENTS_MAXIMUM_SIZE_BYTES` | not validated in zig |
45| max_related_resources | n/a | 100 | `PREFECT_SERVER_EVENTS_MAXIMUM_RELATED_RESOURCES` | not validated |
46| max_labels_per_resource | n/a | 500 | `PREFECT_SERVER_EVENTS_MAXIMUM_LABELS_PER_RESOURCE` | not validated |
47| retention_period | n/a | 7 days | `PREFECT_SERVER_EVENTS_RETENTION_PERIOD` | not implemented |
48| websocket_backfill_page_size | 250 | 250 | `PREFECT_SERVER_EVENTS_WEBSOCKET_BACKFILL_PAGE_SIZE` | ✅ matches |
49| max_websocket_backfill | 15min | 15min | `PREFECT_SERVER_EVENTS_MAXIMUM_WEBSOCKET_BACKFILL` | ✅ matches |
50
51## logging
52
53| setting | zig value | python default | python env var | notes |
54|---------|-----------|----------------|----------------|-------|
55| level | WARNING | WARNING | `PREFECT_SERVER_LOGGING_LEVEL` | ✅ matches |
56
57## deployments
58
59| setting | zig value | python default | python env var | notes |
60|---------|-----------|----------------|----------------|-------|
61| schedule_max_runs | n/a | 50 | `PREFECT_SERVER_DEPLOYMENT_SCHEDULE_MAX_SCHEDULED_RUNS` | scheduler not implemented yet |
62
63## datetime handling
64
65| aspect | zig implementation | python | notes |
66|--------|-------------------|--------|-------|
67| format | ISO 8601 (`2025-01-21T12:34:56.123456Z`) | ISO 8601 | ✅ matches |
68| timezone | UTC (Z suffix) | UTC-aware | ✅ matches |
69| precision | microseconds | microseconds | ✅ matches |
70| storage | TEXT column | TIMESTAMP column | sqlite/postgres both use TEXT for consistency |
71| parsing | supports multiple formats | pydantic datetime | handles SQLite/postgres/ISO formats |
72
73### utilities (`src/utilities/time.zig`)
74- `timestamp()` - generate current time as ISO 8601 string
75- `nowMicros()` - get current time as microseconds since epoch
76- `parse()` - parse ISO 8601 strings (handles `T`/space separator, optional micros, timezone)
77- `lessOrEqual()` - compare two timestamp strings
78- `isPast()` - check if timestamp is in the past
79
80### schema defaults
81- SQLite: `strftime('%Y-%m-%dT%H:%M:%fZ', 'now')` - ISO 8601 with 3-digit millis
82- PostgreSQL: `TO_CHAR(NOW() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"')` - ISO 8601 with 6-digit micros
83
84## remaining work
85
86### medium priority (production safety)
87- add database statement timeout
88- add event size validation
89- add keepalive timeout support
90
91### low priority (completeness)
92- event retention cleanup service
93- deployment scheduler service