Skip to content

Store & Forward and Data Infrastructure ​

Last updated

License feature: Store & Forward

Store & forward keeps data that could not be written — because InfluxDB or a remote database was unavailable — on the appliance, and sends it when the target is back. The Data Infrastructure page shows those buffers and also holds the SQL historian settings, transaction groups and outbound REST calls.

Where and who ​

Visualize → Data Infrastructure (/data-infra). The sidebar entry appears when any of store_forward, transaction_groups or rest_api_outbound is licensed and available to you. The page has up to five tabs, each shown only when its feature is licensed:

TabNeedsCovers
Historianstore_forward, and the admin roleWhere tag history is stored (InfluxDB, SQL, or both)
InfluxDB S&Fstore_forwardBuffered InfluxDB writes and the quarantine
Remote DB S&Fstore_forward + remote_databasesBuffered remote database writes
Transaction Groupstransaction_groupsSee Transaction Groups
Outbound APIrest_api_outboundSee Outbound REST

Anyone with the feature can view the buffers. Retry, Purge, quarantine actions and historian settings need admin.

The Historian tab is shown to admins only, because its settings are admin-only.

What is buffered ​

WriteBuffered?Where
Tag history and other points written to InfluxDBYesstore_forward_buffer table in the configuration database
Smart Assist sample batches to InfluxDBNo — dropped while InfluxDB is down
Data Tables editor and script writes to included remote tablesYesremote_db_forward_buffer table
Transaction group rows to a remote database, when run by their triggerYesremote_db_forward_buffer table
Inserts into included SQL Server tablesNo — the caller gets the error
Named-query writes to a remote databaseNo
SQL historian rowsIn memory only (below)
Sparkplug, outbound REST, workflow HTTP callsNo

Without the store_forward license nothing is buffered: InfluxDB points written during an outage are lost, and remote-table writes are lost while still reporting success.

InfluxDB store & forward ​

When a write to InfluxDB fails (InfluxDB not answering its health check, or an error response), the point is stored in SQLite instead.

  • Replay: every 15 seconds, up to 500 entries at a time by default (see Forwarding settings below), oldest first, as one request with a 10-second timeout. A pass still running when the next is due is not started twice.
  • InfluxDB still down: entries stay Pending and are retried indefinitely; the attempt count does not grow.
  • InfluxDB answers 5xx: each attempt counts; after 10 attempts the entry becomes Failed.
  • InfluxDB rejects the data (4xx) — a field type conflict, an unparseable line: the batch is split until the bad entries are found; good entries are sent and the bad ones go straight to Failed with InfluxDB's reason.
  • Size limit. The buffer holds at most Store & forward buffer limit rows (Settings → Data Retention, 1,000,000 by default — roughly 250 MB). When it is full, rows are removed in this order: sent entries first, then quarantined (Failed) entries, and the oldest pending entries last, so the newest readings are kept. Every time unsent entries are dropped, the appliance logs a warning, writes an entry to the audit log, and the card shows how many were dropped and when. Set the limit to 0 for no limit.
  • Sent entries are deleted automatically once they are older than Delivered store & forward rows (7 days by default). Purge Sent (7d+) does the same on demand.

InfluxDB Buffer Status card:

ItemMeaning
PendingWaiting to be sent
SentAlready delivered (kept for reference)
FailedGave up — these are the same entries listed under Quarantine
TotalAll entries in the buffer
Buffer limit lineThe row limit from Settings → Data Retention, and a warning if unsent entries were ever dropped for it
Oldest pending entryTimestamp of the oldest unsent point — how far behind history is
Retry FailedPut every failed entry back to pending
Purge Sent (7d+)Delete sent entries older than 7 days

Forwarding settings ​

Each buffer tab has a Forwarding box at the top of its status card:

FieldWhat it doesDefault (InfluxDB / Remote DB)Limits
Every (seconds)Time between forwarding passes15 / 201–600
Rows per passMost entries sent in one pass (per connection, for remote databases)500 / 1001–5000

Click Save forwarding; the new values take effect immediately, without a restart. Only an admin can change them; everyone else sees them read-only. Larger batches and shorter intervals catch up faster after a long outage but put more load on the destination and on the appliance. Below the fields the box shows when entries were last forwarded and how many ("Last forwarded n row(s) at …"), and "Last attempt failed: …" with the reason when the most recent pass failed. The change is written to the audit log.

Quarantine lists failed writes with the measurement, time, attempts and InfluxDB's reason, 25 per page. Select entries and Retry after fixing the cause, or Discard them (Empty quarantine discards all). Discarding is permanent data loss and is written to the audit log.

Tags opens InfluxDB - Tag Notifications, where you can pick three tags that Scada.Ink sets to true/false: Buffering (connection lost), Forwarding In Progress and Forwarding Complete. Use local tags, and use them in alarms, workflows or a dashboard indicator. They are set in Scada.Ink only, never written to a PLC, and they can be wrong just after a restart. Click Save Tag Config.

Remote database store & forward ​

  • Replay: every 20 seconds, up to 100 operations per connection by default (see Forwarding settings above), in the order they were made. The first is tried as a probe; replay for that connection stops at the first failure.
  • Retries: after 10 failed attempts an operation becomes Failed and the ones behind it can proceed.
  • The Remote DB S&F tab shows Pending, Sent, Failed, Oldest pending entry, Pending by Connection, Retry Failed and Purge Sent (7d+), plus the same three notification tags (for all connections together).

Warning: An operation is buffered whatever the reason it failed, including SQL errors that will never succeed. Such an operation holds up every later write to that connection for ten replay attempts (about three minutes) before it is marked failed. Operations for a deleted connection stay in the buffer.

SQL historian (Historian tab) ​

The Historian tab chooses where tag history is written. Details of history itself are in Historian Storage.

OptionBehavior
InfluxDBThe built-in time-series database. The default
Both (migrating)Write to both, read from SQL. Use while you verify the SQL copy
SQL onlyWrite to and read from a remote database connection
FieldWhat it doesDefaultLimits
SQL connectionWhich remote database (see Remote Databases)noneRequired for SQL and Both
Table nameTable to writetag_historyLetters, digits, underscore; up to 63 characters
Batch sizeRows per INSERT5001–5000
Flush interval (ms)How often a partial batch is written2000250–60000
Retention (days)Delete older rows every 6 hours0 (keep forever)0–3650

Buttons: Save; then Create / verify table (creates device_id, tag_path, data_type, num_value, str_value, ts with an index), Flush now, and Prune now when retention is set. Changing the backend affects new history only.

  • The SQL write buffer is in memory, up to 50,000 rows. If the database is unreachable long enough to fill it, the oldest rows are dropped and counted under dropped in Backend status. Rows still in memory are lost if the API restarts.
  • On SQL Server, each flush is automatically capped at 333 rows regardless of Batch size — each row uses 6 parameters and SQL Server allows 2100 per statement. A Batch size above that just splits across more flushes rather than failing; the setting works as configured on MySQL, PostgreSQL, ODBC and Oracle.
  • Oracle versions before 23ai do not accept the multi-row insert the historian uses.
  • A raw query over a range with more than 1000 points returns about 1000 per-window averages spanning the whole range, and an aggregation window too small to fit the range in 2000 points is widened. ODBC connections cannot aggregate, so a long range there returns the newest 1000 raw points.

Backend status (refreshes every 10 seconds) shows which backend serves reads, whether InfluxDB is reachable, the SQL table, rows pending and dropped, the last write and the last error.

History rollups, below it, turns the hourly and daily rollups on or off, shows how many historized tags are up to date and how many rollup rows are kept, and has Run now. See Historian Storage.

API ​

MethodPathRolePurpose
GET/api/data-infra/store-forward/statsviewerInfluxDB buffer counts, forwarding interval and batch size, last pass
GET/api/data-infra/store-forward/settingsviewer{ influx: { flushIntervalMs, batchSize }, remoteDb: { … } }
PUT/api/data-infra/store-forward/settingsadminChange either or both; out-of-range values answer 400
POST/api/data-infra/store-forward/retry-failedadminRetry every failed entry
POST/api/data-infra/store-forward/purgeadmin{ olderThanDays } (default 7) — delete sent entries
GET/api/data-infra/store-forward/quarantineviewerFailed entries; limit ≤ 200, offset
POST/api/data-infra/store-forward/quarantine/retryadmin{ ids }
POST/api/data-infra/store-forward/quarantine/discardadmin{ ids } or { all: true }
GET/api/data-infra/remote-db-forward/statsviewerRemote DB buffer counts
GET/api/data-infra/remote-db-forward/entriesviewerBuffered operations; status, limit
POST/api/data-infra/remote-db-forward/retry-failedadminRetry failed operations
POST/api/data-infra/remote-db-forward/purgeadminDelete old sent operations
GET/api/data-infra/sf-tags/influxviewerNotification tags (InfluxDB)
PUT/api/data-infra/sf-tags/remotedb/:connectionIdadminNotification tags for one connection, or global
GET/api/historian/settingsadminSQL historian settings
PUT/api/historian/settingsadminSave them

Troubleshooting ​

SymptomCauseFix
Pending keeps growingInfluxDB or the database is still downFix the target; replay starts on its own within one forwarding interval (15–20 s by default)
Failed entries with a field type conflictA tag changed data type, so InfluxDB refuses the new typeFix or discard; InfluxDB keeps the first type per field
ids must be a non-empty array of entry idsRetry/Discard called with nothing selectedSelect entries
The buffer shows dropped entriesAn outage lasted long enough to fill the bufferFix the target; raise the limit under Settings → Data Retention if storage allows
Select a SQL connection before enabling the SQL backendSQL or Both chosen without a connectionPick SQL connection
The selected remote connection is disabledConnection disabledEnable it
dropped count risingSQL database unreachable and the 50,000-row buffer is fullRestore the database; the dropped rows are gone

See also ​

Scada.Ink Help Center