Configuration reference¶
This page describes the main plotsrv.yaml settings.
Create a starter config with:
The default file is intentionally compact and exposes the main settings: storage, watched-file materialisation, async publishing, safety limits, freshness checks, and concise browser errors. Storage is off by default. For less commonly adjusted storage queue and rendering controls, use:
plotsrv still runs without a config file. Add config when you want stable limits, storage, freshness, rendering, or security behaviour across runs.
Starter layout¶
A compact starter config looks like this:
# Storage is off by default. Enable it for latest restore and history.
storage-settings:
enabled: false
watch_enabled: false
root_dir: .plotsrv/store
max_snapshot_size_mb: 20.0
default_keep_last: 2
default_min_store_interval: off
latest:
enabled: true
restore_on_startup: true
restore_scope: discovered
watch-settings:
# auto = memory below file_threshold_mb, file-backed at or above it.
materialization: auto
file_threshold_mb: 10
publish-settings:
live:
async_enabled: false
limits:
published_objects:
max_plot_bytes: 5242880
max_table_rows: 100000
max_table_columns: 200
watched_files:
max_mb: 500
truncate_after:
text: 1000000
markdown: 100000
html: off
table_rows: 100000
table_columns: 200
freshness-settings:
enabled: false
security-settings:
tracebacks_enabled: false
The --expanded form adds storage queue bounds and rendering settings shown
throughout this reference.
limits¶
limits is split into three concepts:
| Section | Purpose |
|---|---|
published_objects |
hard safety limits for objects sent to /publish |
watched_files |
how much plotsrv reads from watched files |
truncate_after |
how much plotsrv prepares/displays |
limits.published_objects¶
These are hard server-side safety limits.
If a normal Python publish exceeds one of these values, the request is rejected. The browser UI also receives a visible publish_error artifact explaining what failed and which key to adjust.
limits:
published_objects:
max_plot_bytes: 5242880
max_table_rows: 100000
max_table_columns: 200
max_artifact_text_chars: 200000
max_json_container_items: 20000
| Key | Meaning |
|---|---|
max_plot_bytes |
maximum decoded plot/image payload size |
max_table_rows |
maximum table rows accepted by /publish |
max_table_columns |
maximum table columns/fields accepted by /publish |
max_artifact_text_chars |
maximum text representation accepted for text-like artifacts |
max_json_container_items |
maximum item count for JSON-like containers |
publish-limits is still accepted as a legacy fallback, but new configs should use limits.published_objects.
limits.watched_files¶
Controls how much plotsrv reads for watched-file previews.
| Key | Meaning |
|---|---|
max_mb |
maximum amount read for each watched-file preview |
Use off to allow full-file reads:
max_bytes is still accepted as a legacy alias, but new configs should use max_mb.
The equivalent CLI option is:
--max-bytes remains available as a legacy/advanced CLI option.
Watched-file materialization¶
Watched files can be memory-backed or file-backed.
| Mode | Behaviour |
|---|---|
memory |
reads watched-file content and publishes a normal in-memory view |
file |
stores watched-file metadata and reads bounded previews from disk on demand |
auto |
uses file_threshold_mb to choose between memory and file |
In auto mode, files at or above file_threshold_mb become file-backed.
You can force a mode from the CLI:
or for watched files attached to plotsrv run:
File-backed watched views are useful for large logs and CSVs because plotsrv does not retain the full file content in server memory.
File-backed active loads¶
watch-settings.active_loads bounds concurrent on-demand preview work for
file-backed views. It does not change what users may see: table display limits
remain under limits.truncate_after.
When all slots are active, plotsrv responds with a temporary 503 and
Retry-After header. The browser retries briefly; API clients can make the
same decision explicitly.
limits.truncate_after¶
Controls preparation/display truncation.
limits:
truncate_after:
text: 1000000
markdown: 100000
html: off
table_rows: 100000
table_columns: 200
| Key | Meaning |
|---|---|
text |
maximum characters prepared for normal text artifacts |
markdown |
maximum characters prepared for markdown artifacts |
html |
maximum characters prepared for HTML artifacts; off disables truncation |
table_rows |
maximum table rows prepared for display |
table_columns |
maximum table columns prepared for display |
Generated plotsrv error artifacts use watch_error or publish_error and are not truncated by normal text limits. This keeps actionable error messages visible even when text truncation is low.
Legacy limits.render, limits.tables, and top-level truncation settings are still accepted where possible, but new configs should use limits.truncate_after.
publish-settings¶
Live publishing is synchronous by default. This preserves existing behaviour and needs no configuration for ordinary scripts.
For high-frequency live status/table/plot updates, this optional section makes
the bounded latest-wins worker the default when callers leave async_ unset:
publish-settings:
live:
async_enabled: true
max_pending_views: 32
max_pending_mb: 64
flush_timeout_s: 1.0
| Key | Meaning |
|---|---|
async_enabled |
default for publish_view(..., async_=None); false by default |
max_pending_views |
maximum distinct destination/view updates retained before processing |
max_pending_mb |
maximum estimated memory retained by pending source objects |
flush_timeout_s |
short default timeout used by flush_views() and attached-server shutdown |
The queue is for replaceable live views only. For one destination/view, a newer
pending update replaces the older one. New views are rejected once either budget
is full. Inspect /status for publish_queue counters rather than assuming
that a high-volume update was delivered.
For @view, this setting selects synchronous or asynchronous delivery only
after the decorator is active through host, port, or launch_server. It
does not turn a metadata-only @view(...) declaration into a publisher.
render-settings¶
render-settings.default controls renderer behaviour.
render-settings:
default:
plot_dpi: 200
plot_default_figsize_in: "12,6"
plot_bbox_tight: true
plot_pad_inches: 0.10
table_plot_max_points: 5000
table_view_mode: rich
html_sanitize: false
markdown_sanitize: true
html_sandbox: ""
markdown_sandbox: ""
| Key | Meaning |
|---|---|
plot_dpi |
DPI used when rendering static plot images |
plot_default_figsize_in |
default matplotlib-style figure size |
plot_bbox_tight |
save plots with tight bounding boxes |
plot_pad_inches |
plot padding when tight bounding boxes are used |
table_plot_max_points |
maximum SVG points in a browser table plot (default 5000, hard-capped at 25000); larger plots offer browser-side sampling |
table_view_mode |
rich or simple table mode |
html_sanitize |
sanitize HTML artifacts before rendering |
markdown_sanitize |
sanitize rendered markdown HTML |
html_sandbox |
optional iframe sandbox value for HTML |
markdown_sandbox |
optional iframe sandbox value for markdown |
Legacy table-settings and artifact-render-settings are still readable, but new config should use render-settings.default.
storage-settings¶
Storage controls latest restore and historical snapshots.
storage-settings:
enabled: true
watch_enabled: false
root_dir: .plotsrv/store
latest:
enabled: true
restore_on_startup: true
restore_scope: discovered
streams:
enabled: true
summary_retention: 32
noteworthy_keep_last: 32
keep_last_sessions: 4
max_bytes_per_view_mb: 16
# Omit or set to null for compact-only history.
raw_retention: null
default_keep_last: 2
default_min_store_interval: off
max_snapshot_size_mb: 20.0
max_pending_tasks: 32
max_pending_mb: 64
storage-settings.enabled is the master switch. If it is false, storage is off even if nested settings are present.
max_pending_tasks and max_pending_mb bound best-effort latest/snapshot
serialisation work. Rejections are exposed as storage_queue counters in
/status; they never affect the in-memory live view that has already been
accepted.
Stream-session storage¶
storage-settings.streams controls bounded persistence for structured stream
sessions. storage-settings.enabled remains the master switch. A compact
session stores metadata, derived summaries, and noteworthy/continuity items;
it does not turn a restarted producer into a live session.
| Key | Meaning |
|---|---|
enabled |
Enable compact stream persistence while master storage is enabled. |
summary_retention |
Maximum derived windows retained for each session. |
noteworthy_keep_last |
Maximum noteworthy/continuity items retained for each session. |
keep_last_sessions |
Softer count limit for retained sessions per logical stream. |
max_bytes_per_view_mb |
Hard combined ceiling for compact files, markers, and raw blocks for one logical stream. |
raw_retention |
Explicit raw-segment policy; null disables raw persistence. |
raw_retention, when present, accepts max_blocks, max_bytes_mb, and
optional max_age_s. The hard max_bytes_per_view_mb ceiling wins whenever
these policies conflict. A per-view override belongs at
storage-settings.views.<view_id>.stream (the early streams spelling is
also accepted).
Source-aware storage¶
Watched-file snapshots are disabled by default.
File-backed watched files are always skipped by storage. They are represented by metadata and previewed from the source file on demand, so plotsrv does not write latest-state payloads or snapshots for them.
To snapshot memory-backed watched files globally:
To opt in one memory-backed watched view:
Normal Python publishes use views.<view_id>.enabled; watched-file publishes use views.<view_id>.watch_enabled.
freshness-settings¶
Freshness shows whether a view has updated recently enough.
| Key | Meaning |
|---|---|
expected_every |
expected update cadence |
warn_after |
threshold for stale/warning state |
overdue_after |
threshold for overdue/error state |
Source-aware freshness¶
Global freshness applies to normal Python publishes.
Watched-file views are not marked stale by global freshness settings by default. To apply freshness to a watched file, opt that specific view in:
freshness-settings:
enabled: true
views:
"files:job log":
enabled: true
expected_every: 5m
warn_after: 10m
overdue_after: 30m
This avoids marking static but valid watched files as stale.
security-settings¶
Security settings control optional routes and local-only behaviour.
security-settings:
tracebacks_enabled: false
docs_enabled: false
openapi_enabled: false
shutdown_enabled: false
control_local_only: true
internal_read_local_only: false
status_local_only: false
history_local_only: false
views_local_only: true
The generated starter config only includes tracebacks_enabled, but the full set can be added when needed.
Populating config¶
plotsrv can scan Python code for discoverable views:
plotsrv config populate freshness .
plotsrv config populate storage .
plotsrv config populate limits .
For limits, generated entries use the current schema:
limits:
published_objects:
max_plot_bytes: 5242880
max_table_rows: 100000
max_table_columns: 200
max_artifact_text_chars: 200000
max_json_container_items: 20000
watched_files:
max_mb: 500
truncate_after:
text: 1000000
markdown: 100000
html: off
table_rows: 100000
table_columns: 200
views:
"pipelines:daily import":
truncate_after:
text: 1000000
markdown: 100000
html: off
Use --mode merge to preserve existing entries and add new ones, or --mode replace to regenerate the discovered entries.
Legacy compatibility¶
The following legacy sections remain readable for compatibility:
publish-limits:
limits:
watched_files:
max_bytes:
render:
tables:
truncation:
table-settings:
artifact-render-settings:
New documentation and generated configs use the newer layout.