configuration audit#
comparison of magic values in zig implementation vs python prefect server settings.
status: most high-priority items addressed, remaining items are medium/low priority
http server#
| setting |
zig value |
python default |
python env var |
notes |
| port |
4200 |
4200 |
PREFECT_SERVER_API_PORT |
✅ matches |
| host |
127.0.0.1 |
127.0.0.1 |
PREFECT_SERVER_API_HOST |
✅ matches |
| workers |
1 |
1 |
--workers CLI flag |
✅ matches |
| threads |
4 |
n/a |
- |
zap/facil.io specific; python uses async |
| max_clients |
1000 |
n/a |
- |
zap/facil.io specific; uvicorn unlimited |
| max_body_size |
16MB |
n/a |
- |
uvicorn default is unlimited |
| keepalive_timeout |
n/a |
5s |
PREFECT_SERVER_API_KEEPALIVE_TIMEOUT |
not implemented in zig |
notes#
- threads/workers: zap's model is different (threads per worker). 4 threads × 1 worker is reasonable for single-process mode
- max_body_size: 16MB is reasonable; python has no limit which could be a DoS vector
api behavior#
| setting |
zig value |
python default |
python env var |
notes |
| default_limit |
200 |
200 |
PREFECT_SERVER_API_DEFAULT_LIMIT |
✅ matches (all endpoints) |
database#
| setting |
zig value |
python default |
python env var |
notes |
| pool_size |
5 |
5 |
PREFECT_SERVER_DATABASE_SQLALCHEMY_POOL_SIZE |
✅ matches |
| max_overflow |
n/a |
10 |
PREFECT_SERVER_DATABASE_SQLALCHEMY_MAX_OVERFLOW |
not applicable to pg.zig |
| pool_recycle |
n/a |
3600s |
- |
not implemented |
| statement_timeout |
n/a |
10s |
PREFECT_SERVER_DATABASE_TIMEOUT |
not implemented |
| connection_timeout |
n/a |
5s |
PREFECT_SERVER_DATABASE_CONNECTION_TIMEOUT |
not implemented |
events#
| setting |
zig value |
python default |
python env var |
notes |
| max_event_size |
n/a |
1.5MB |
PREFECT_SERVER_EVENTS_MAXIMUM_SIZE_BYTES |
not validated in zig |
| max_related_resources |
n/a |
100 |
PREFECT_SERVER_EVENTS_MAXIMUM_RELATED_RESOURCES |
not validated |
| max_labels_per_resource |
n/a |
500 |
PREFECT_SERVER_EVENTS_MAXIMUM_LABELS_PER_RESOURCE |
not validated |
| retention_period |
n/a |
7 days |
PREFECT_SERVER_EVENTS_RETENTION_PERIOD |
not implemented |
| websocket_backfill_page_size |
250 |
250 |
PREFECT_SERVER_EVENTS_WEBSOCKET_BACKFILL_PAGE_SIZE |
✅ matches |
| max_websocket_backfill |
15min |
15min |
PREFECT_SERVER_EVENTS_MAXIMUM_WEBSOCKET_BACKFILL |
✅ matches |
logging#
| setting |
zig value |
python default |
python env var |
notes |
| level |
WARNING |
WARNING |
PREFECT_SERVER_LOGGING_LEVEL |
✅ matches |
deployments#
| setting |
zig value |
python default |
python env var |
notes |
| schedule_max_runs |
n/a |
50 |
PREFECT_SERVER_DEPLOYMENT_SCHEDULE_MAX_SCHEDULED_RUNS |
scheduler not implemented yet |
datetime handling#
| aspect |
zig implementation |
python |
notes |
| format |
ISO 8601 (2025-01-21T12:34:56.123456Z) |
ISO 8601 |
✅ matches |
| timezone |
UTC (Z suffix) |
UTC-aware |
✅ matches |
| precision |
microseconds |
microseconds |
✅ matches |
| storage |
TEXT column |
TIMESTAMP column |
sqlite/postgres both use TEXT for consistency |
| parsing |
supports multiple formats |
pydantic datetime |
handles SQLite/postgres/ISO formats |
utilities (src/utilities/time.zig)#
timestamp() - generate current time as ISO 8601 string
nowMicros() - get current time as microseconds since epoch
parse() - parse ISO 8601 strings (handles T/space separator, optional micros, timezone)
lessOrEqual() - compare two timestamp strings
isPast() - check if timestamp is in the past
schema defaults#
- SQLite:
strftime('%Y-%m-%dT%H:%M:%fZ', 'now') - ISO 8601 with 3-digit millis
- PostgreSQL:
TO_CHAR(NOW() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"') - ISO 8601 with 6-digit micros
remaining work#
medium priority (production safety)#
- add database statement timeout
- add event size validation
- add keepalive timeout support
low priority (completeness)#
- event retention cleanup service
- deployment scheduler service