Changelog
Release notes for the Open Source edition can be found on github.
Unreleased
- New connector (
nats_output): write view output to a NATS subject. The connector publishes to JetStream: each message is acknowledged by the server before the pipeline moves on, every message carries aNats-Msg-Idderived from its content so that output replayed after a restart is deduplicated by the server within the stream's duplicate window, and static headers can be attached to every message. The message size limit is discovered from the bound stream at connect time (the stream'smax_message_size, else the server's max payload) and can be overridden; a record over the limit fails the pipeline with an error naming the record and the limit, instead of reaching the server. See NATS output connector.
v0.362.0
-
Incompatible change (SQL): the
emit_finalproperty of a view must specify a column name. The documentation also allowed a column number, such as'emit_final' = '0', but the compiler ignored numeric values: the view emitted every change, as if it had noemit_finalproperty. A column number is now a compilation error. Seeemit_final. -
Incompatible change (SQL): a view with an
emit_finalproperty can no longer be used in the definition of another view. The other view read the rows beforeemit_finalheld them back, not the final rows. Define a separate view withoutemit_finaland use that view instead. Seeemit_final.
v0.360.0
-
Storage now uses LZ4 compression by default, instead of Snappy. LZ4 compresses better in about the same amount of time and decompresses several times faster.
-
Incompatible change (SQL):
PARSE_JSONnow fails at runtime if its argument is not valid JSON. It used to return a value thatIS NULLdid not recognize asNULL, although the documentation promised a SQLNULL. The new functionTRY_PARSE_JSONreturns a SQLNULLfor invalid JSON; replacePARSE_JSONwithTRY_PARSE_JSONin programs whose input may hold invalid JSON. SeeTRY_PARSE_JSON.
v0.358.0
-
Incompatible change (SQL): a
RANGEwindow frame with a bound of the formn PRECEDINGorn FOLLOWINGnow requires anORDER BYcolumn that cannot beNULL. A program using e.g.,RANGE BETWEEN INTERVAL 1 DAY PRECEDING AND CURRENT ROWover a nullable timestamp, now fails to compile. This can be worked around by declaring the columnNOT NULL, or by filtering out theNULLvalues first, for example withWHERE ts IS NOT NULL. See Unsupported operations. -
Bug fix (Python SDK):
Pipeline.listen()andPipeline.foreach_chunk()returned aNULLvalue of aCHARorVARCHARcolumn as the string'None'. These columns now have the pandas typestring, so aNULLvalue is a missing value (Noneinto_dict()), andpandas.isna()finds it.
v0.356.0
-
Bug fix (SQL):
DATEDIFF(QUARTER, left, right)mixed whole years with calendar quarters and often returned wrong values; for example,DATEDIFF(QUARTER, DATE '2020-06-15', DATE '2021-01-01')returned -1 instead of 2. It now divides the elapsed months by 3, asTIMESTAMPDIFF(QUARTER, left, right)does, so views using it may produce different results after they are recompiled. -
Incompatible change (user-defined aggregates): the accumulator type of a user-defined aggregate written in Rust must now implement
dbsp::dynamic::OrdReprfor its rkyv archived form, so that an archived value can be ordered against an unarchived one without deserializing it. Storage searches file-backed data by comparing archived keys, and every type that can be a key or a value of a Feldera collection needs the comparison; the same therefore holds for any type used as a key or a value with thedbspcrate's Rust API. A type whoseArchiveandOrdare both derived can add#[derive(feldera_macros::OrdRepr)], which compares the fields in the order#[derive(Ord)]does. A type with a hand-writtenArchiveimplementation, such as theI256Wrapperaccumulator in the documentation, needs a hand-writtenimpl OrdRepr<T> for ArchivedTwhoseord_cmpagrees with the type'sOrdon every pair of values; a disagreement makes lookups return wrong rows. Without the implementation the pipeline fails to compile withthe trait bound ... OrdRepr<...> is not satisfied. See User-defined aggregates.
v0.352.0
- Cluster monitoring data that has gone stale is now reported as such
instead of being served as current. The cluster monitor is the only
writer of cluster monitor events, and in the enterprise edition it runs
within the runner, so when the runner dies, its last write kept reporting
every service healthy indefinitely. Once the latest event is older than
30 minutes it carries
stale: true,GET /v0/cluster_healthzreportsall_healthy: falseand answers503, and the web console shows a banner instead of an "Operational" status. This also affects retries: the Rust and Python clients call that endpoint after a502to decide whether to retry immediately, so while monitoring is down they wait their fixed pause instead.
v0.351.0
-
Incompatible change (PostgreSQL CDC input connector): an unqualified
source_tablenames a table in thepublicschema. A pipeline whosesource_tablegives a bare name for a table outsidepublicno longer matches that table, and fails to start with an error that lists the tables the publication carries. Give the qualified name instead, for example"sales.orders". See PostgreSQL CDC input connector. -
The PostgreSQL CDC input connector never checkpoints part of a table's initial read. It blocks checkpoints and suspend requests until the whole read has reached the circuit and the connector's replication state records it, which can take as long as the read of a large table, longer while the pipeline is paused, and may need a forced stop. A pipeline that stops or crashes before a read finishes, a fault-tolerant pipeline that starts with no checkpoint, and a pipeline that resumes from a checkpoint taken before a later read of the table finished all read the table again; a primary key on the Feldera table makes the repeated rows replace the originals. After upgrading, a fault-tolerant pipeline whose table had no changes since its initial read reads it once more, because earlier checkpoints carry no record of the read. See PostgreSQL CDC input connector.
-
Bug fix (PostgreSQL CDC input connector): a fault-tolerant pipeline no longer loses changes when it crashes. The connector reads changes in batches, and it could tell PostgreSQL that a batch was safely held while part of that batch was still on its way into the pipeline. A checkpoint taken at that moment held only the part that had arrived, while PostgreSQL, told it could move on, stopped offering the rest, so a crash before the next checkpoint lost those changes. The connector now reports a batch only once all of it has arrived, and waits for the checkpoint that holds it rather than for one that may predate it when an output connector runs behind. Stopping a pipeline now also reports the batches a checkpoint already holds, instead of leaving them unreported: an unreported batch made the next start read the whole source table again, which a large table made expensive (#7122). See PostgreSQL CDC input connector.
-
The PostgreSQL CDC input connector moves to a newer etl. It no longer fails intermittently with
Missing shared table statewhen a table hands off from its initial read to streaming. etl runs more migrations on the source database: a second source migration extends itsALTER TABLEevent trigger toALTER PUBLICATION, which needs the same superuser privileges as the first, and four state-store migrations, one of which retypes thesnapshot_idcolumns in schemaetl, so an earlier Feldera version cannot start a CDC pipeline against a source database this version has migrated unless theetlschema is dropped first, which repeats every table's initial read. The initial read uses etl's current defaults: batches of up to 32 MiB instead of 8 MiB and four copy connections per table instead of two. See PostgreSQL CDC input connector.
v0.350.0
-
The pipeline logs stream can be resumed instead of replayed from the start of the buffer. Passing
cursor=<epoch>:<sequence>toGET /v0/pipelines/{pipeline}/logsreturns only the lines that follow that position, and the response reports where the stream starts in thefeldera-logs-epoch,feldera-logs-seqandfeldera-logs-gapheaders. A request without acursorbehaves as before. In Python, usePipeline.resume_logsorFelderaClient.resume_pipeline_logs, which returns the open stream and itsLogPosition. -
Bug fix (Delta Lake input connector,
cdcmode): a CDC read no longer decodes columns the pipeline does not need. A column the SQL table never declares, and that no connector expression names, is left out of the read. This also fixes a transaction such asUPDATEorMERGEthat rewrote a file while changing only such a column: itsaddandremoveactions did not cancel, and the connector re-emitted the rewritten rows as inserts (#7116). -
Bug fix (Delta Lake input connector): a Unity Catalog Uniform table read every column as NULL in
followandcdcmode and in the follow half ofsnapshot_and_follow. Its columns are now matched by field id. -
Bug fix (Delta Lake input connector,
cdcmode): auc://table read no rows from a commit's files unless they carried a deletion vector. Such a table's location is path-less, so the listing the read planned resolved to nothing (#7112). -
Bug fix (Delta Lake input connector): a struct nested in an array or a map of a column-mapped table read its neighbor's values in
followandcdcmode, because its fields were paired by name and such a file shares no field name with the table's schema. -
Bug fix (Delta Lake input connector,
snapshotmode): a struct nested in an array or a map of an id-mapped table read its fields exchanged when the log listed them in a different order than the data file. A container's children are now relabeled by field id before the struct cast pairs them (#7279). -
Incompatible change (Delta Lake input connector): in
followandcdcmode a data file holding a null element of an array or a map the Delta table declaresNOT NULLis now rejected. Such a file used to read through, so a pipeline ingesting one now fails where it did not before. -
Incompatible change (SQL compiler): the
WATERMARKcolumn annotation is removed, and a table that declares one no longer compiles. There is no replacement. The annotation was experimental and undocumented, and a table that combined it with aPRIMARY KEYnever compiled.WATERMARKis no longer a reserved keyword, so a program may use it as an identifier, and a column'swatermarkproperty no longer appears in a program's schema. -
The Kafka connector's
sasl.mechanism = OAUTHBEARERauthentication can now target GCP Managed Service for Apache Kafka, in addition to AWS MSK. Set the newoauth_providerfield togcpto mint tokens from Google Application Default Credentials, including the GKE metadata server under Workload Identity. See Kafka input connector (#6886). -
The NATS input connector implements the authentication methods its schema already declared: a bare
nkeyseed (Ed25519 challenge-response),jwtwith the seed that signs the connection nonce (decentralized/operator-mode auth with the JWT and seed as two secrets rather than one.credsfile),token, anduser_and_password. Previously onlycredentialstook effect and the rest were silently ignored; configuring more than one method is now rejected. A newtlssection inconnection_configsetsrequire_tlsandroot_certificates_filefor servers whose certificates a private CA signs. See NATS input connector. -
Behavior change (SQL compiler): a program that declares
LATENESS, declares anappend_onlytable, or filters withNOW()now gets anUnbounded statewarning for each join, aggregate,DISTINCT, window function, or primary-key index whose state may grow without bound. Existing pipelines of this kind compile with warnings, and a program that setsFELDERA_WARNINGS_ARE_ERRORS = ONfails to compile until the state is bounded or the warning is silenced withSET FELDERA_IGNORE_WARNING_UNBOUNDED_STATE = ON. See Unbounded state warnings. -
The SQL compiler emits the warning
Floating point equalityfor constructs that compareREALorDOUBLEvalues for equality: comparison operators,IN,GROUP BY,DISTINCT,UNION,INTERSECT,EXCEPT,PARTITION BY,NATURAL JOIN,USING, and the ties ofRANK,PIVOT, and the array and map functions that compare elements or keys. Each warning points at the clause that compares.SET FELDERA_IGNORE_WARNING_FLOATING_POINT_EQUALITY = ONsilences it; a program that setsFELDERA_WARNINGS_ARE_ERRORSand compares floating point values no longer compiles until it does. See comparing floating point values.
v0.344.0
-
The Delta Lake and Iceberg input connectors read a
VARIANTcolumn stored in the Parquet variant binary encoding, which is how Delta Lake'svarianttype stores one. Values keep the types the writer encoded, so a date inside aVARIANTarrives as a date rather than as a string. AVARIANTcolumn stored as JSON text still reads as before, and the two can sit side by side in one table. -
Breaking change (Delta Lake output connector): a
VARIANTcolumn is now written as the Deltavarianttype rather than as JSON text in astringcolumn, so values keep the types they have in Feldera. Setvariant_encodingtojson_stringfor the previous encoding, which is also what appending to a table whoseVARIANTcolumn is already astringrequires. See VARIANT.
v0.343.0
-
The
bloom_false_positive_ratestorage setting now applies when a Bloom filter is read as well as when it is written. Lowering it and restarting a pipeline reduces Bloom filter memory without rewriting any batches, and raising it again restores the accuracy the batches were written with. See Memory management.Batches written at a rate finer than 0.1 use a new filter format, so a checkpoint written by this or a later version cannot be resumed by an earlier version. Checkpoints written by earlier versions continue to be read.
v0.340.0
-
Output connectors can be paused, like input connectors: a paused output connector discards the output of its view instead of writing it to its sink, which lets a pipeline run on while a sink is unavailable. Set
pausedin the connector configuration to create it paused, and usePOST /v0/pipelines/{pipeline}/views/{view}/connectors/{connector}/{start,pause}orfda connector <pipeline> <view> <connector> start|pauseat runtime. The connector status reports apausedfield, the web console shows it, and the paused state survives a restart. Output produced while a connector is paused is not replayed when it is started. See connector orchestration. -
Python:
Pipeline.pause_input_connectorandPipeline.start_input_connector(and theirFelderaClientcounterparts) name the kind of connector they act on, matching the newpause_output_connectorandstart_output_connector.pause_connectorandresume_connectorstill work but are deprecated and now raise aDeprecationWarning. -
Breaking change (fda):
--auth-token-commandandFELDERA_AUTH_TOKEN_COMMANDare removed.--oidc-token-fileandFELDERA_OIDC_TOKEN_FILEtake the path of a file holding a bearer token, whichfdareads once per invocation;feldera/oidc-auth-actionv3.0.1 and later export that variable. For a command that prints a token, pass its output as--auth "$(...)".
v0.337.0
-
Breaking change (SQL): comparing a
UUIDwith a character or binary value now converts that value to aUUID, the same direction as comparing a string with a number. Previously theUUIDwas converted to the other operand's type, sou <> ''was alwaysFALSE. A value that does not denote aUUIDis now a runtime error rather than a comparison that silently fails (#6883). -
Breaking change (SQL): converting a string to a
UUIDnow follows PostgreSQL: 32 hexadecimal digits of either case, optionally enclosed in braces, optionally separated by a hyphen after any complete group of four digits. Forms such as123e4567e89b12d3a456426655440000and{123e4567-e89b-12d3-a456-426655440000}are now accepted, while the URN formurn:uuid:123e4567-e89b-12d3-a456-426655440000is rejected, as are strings with leading or trailing blanks. Malformed strings are rejected instead of denoting a differentUUID: the literalUUID '1-2-3-4-5'used to mean00000001-0002-0003-0004-000000000005.UUIDliterals follow the same rules as the cast. Converting a binary value to aUUIDnow requires exactly 16 bytes; a longer value used to be truncated. See UUID operations. -
/checkpointand/checkpoint/syncnow return anincarnation_uuidthat can be used with their corresponding status calls to detect if the pipeline restarts. If it does, the operation itself must be restarted (the most common use of the Python API does this automatically).
v0.333.0
-
Breaking change (SQL):
=,<>and!=are no longer allowed betweenROWvalues, so some programs that used to compile are now rejected. The previous implementation of these operations did not follow the standard SQL semantics, which requires thatROW(NULL) = ROW(NULL)evaluates toNULL(in our implementation it would evaluate toTRUE).Instead of these operators, use
IS NOT DISTINCT FROM(or its shorthand<=>) andIS DISTINCT FROMinstead. A user-defined type declared withCREATE TYPE ... AS (...)is aROWtype, so the restriction covers its values too.The restriction also covers the forms that ask for
ROWequality without writing=: a join condition,NATURAL JOIN,USING,IN,CASE value WHEN,NULLIF, and a comparison between two row constructors such as(a, b) = (c, d). See comparingROWvalues for the accepted rewrite of each form. -
Joining on
ROWvalues is now supported, usingON left.r IS NOT DISTINCT FROM right.r(#3398).
v0.330.0
-
Feldera's membership table now authorizes every login: a user acts in the tenants they hold a membership in, whether or not the token's
tenantsclaim names them. The claim, the issuer tenant, and the per-subpersonal tenant become provisioning strategies that create memberships at login, gated by the newauthorization.provisionOnLogin(defaulttrue). Set it tofalseso that access comes only from memberships granted throughPOST /v0/tenant/usersand the web console, with no claim mapping maintained at the identity provider. See Tenant Assignment Strategies and the migration guide. -
Breaking change (revocation): narrowing a token's
tenantsclaim no longer revokes access, because membership rows from past logins stay live. WhileprovisionOnLoginistrue, removing a member does not keep them out either: the claim re-enrolls them on their next login, so full revocation takes both levers. Audit memberships per tenant withGET /v0/tenant/usersbefore or right after upgrading, and see Revoking access. Managed tenancy (thetenantsclaim) is deprecated in favor of Feldera-managed memberships. Two smaller visible changes: some login-path refusals answer403or400where they answered401, and a claim entry a multi-tenant user does not select no longer creates a missing tenant at login (create tenants explicitly withPOST /v0/tenants). -
Member lists now carry the name and email the identity provider holds for each member, and whether that provider vouches for the email, so an administrator recognizes a member without decoding an OIDC
sub.GET /v0/tenant/usersgainsdisplay_nameandemail_verified; the web console's member list andfda member listshow both. -
Renaming a tenant no longer requires updating identity provider claim mappings once
provisionOnLoginisfalse: memberships reference the tenant by id, not by name. -
Owners can retrieve a single tenant by name or identifier through
GET /v0/tenants/{tenant_id}orfda tenant get, so provisioning automation such as an operator reconcile loop checks for a tenant with one request instead of filteringGET /v0/tenants. See Changing your authentication setup. -
POST /v0/tenantsis now idempotent: creating a name that already exists returns the existing tenant with200 OKinstead of failing with409 Conflict, and a fresh name still returns201 Created. Both responses carry the tenant'sid,name, andinitial_provider.fda tenant createis the CLI counterpart.
v0.329.0
- Backward-incompatible change in the
dbspcrate Rust API: theadd_input_setoperator was removed, together with theSetHandletype and the dynamic variantsdyn_add_input_setanddyn_add_input_set_mono. To keep set semantics (duplicate inserts and deletes of absent elements are no-ops), useadd_input_mapwith the element as both key and value; its upsert semantics subsumes set semantics. If the input contains no duplicates,add_input_zsetis a cheaper alternative, but the caller must guarantee that weights stay 0 or 1. SQL pipelines are not affected: the SQL compiler never generated input sets.
v0.328.0
-
Input connectors support the
soft_deleteproperty, which ingests deletions as insertions and reports the original polarity of each record in theis_deletemetadata attribute, so that a table represents the stream of updates it receives rather than the current contents of that stream. See Soft deletes. -
Connectors that ingest columnar data, e.g., Delta Lake, Iceberg, and the Parquet format, now populate columns that default to
CONNECTOR_METADATA(). Previously such a column was alwaysNULLfor these connectors.
v0.327.0
-
Role-based access control (RBAC). Access is now governed by per-user, per-tenant roles (
read<write<admin<owner) rather than every authenticated user having full access to their tenant. See Roles for the model.Upgrading an existing authenticated installation: before RBAC every authenticated user had read and write access; after the upgrade a returning user starts with no membership and is admitted at the configured default role. Set
authorization.defaultRole: write(the binary default isread; the Helm chart sets it towriteinvalues.yaml) so returning users keep their read and write access, and setauthorization.ownersto bootstrap a platform owner, who can then grantadminto whoever manages users and OIDC trust. The default role is applied and recorded on a user's first login after the upgrade, so set it before the first post-upgrade logins; changing it later does not re-grade users who have already logged in (an owner or admin adjusts those individually). TightendefaultRoleback toreadonce explicit roles are provisioned. -
A tenant is now identified by its name alone. Before, a tenant was keyed by
(name, OIDC issuer), so changingauth.issuercreated a second, empty tenant of the same name and stranded the pipelines on the first one, which no login could reach. Logins now resolve the existing tenant across an issuer change. A deployment whose issuer already changed holds two tenants of the same name: the upgrade keeps the name on the one its users reach today and appends the id to the other's name, merging and deleting nothing.GET /v0/tenantslists both. -
Owners can rename a tenant, through
PATCH /v0/tenants/{tenant_id}or the web console's admin page. A rename changes only the name, which is what a login resolves, so it is how an owner reunites users with a tenant they can no longer reach: thedefaulttenant after authentication is switched on, or a tenant left behind by an identity-provider change. Passdisplace_existingto take a name the first login already created a tenant under; that tenant becomes<name> (<id>)and keeps everything it had. See Changing your authentication setup. -
Breaking change (API keys): the
scopesarray on API-key responses (GET /v0/api_keys,GET /v0/api_keys/{api_key_name}) is replaced by a singlerolestring, one ofreadorwrite(lower-case). Clients that read thescopesfield must readroleinstead. Existing keys are migrated towrite, so their access is unchanged. -
Breaking change (API keys): a new key now defaults to
readinstead of carrying read and write access.POST /v0/api_keyswithout arolefield creates aread-only key; pass{"role": "write"}to keep the previous behavior.fda apikey createdefaults to--role readfor the same reason; pass--role writewhere a key needs to make changes.
v0.325.0
- The SQL compiler was incorrectly garbage-collecting input tables with a primary key and a column with LATENESS (#6690). Such tables can only be GC-ed if the column with LATENESS is part of the primary key. As a result some programs that used to run with finite state will now have unbounded state.
v0.322.0
-
Pipeline API field
deployment_runtime_status_detailsis now strongly typed, whereas before it was just a generic JSON value type. WhileAwaitingApproval, the diff is now located atdeployment_runtime_status_details.approval_diffinstead of being the whole details itself. -
Pipelines from v0.322.0 onward will have their GET selector
status_with_connectorsconnector stats cached, which are now updated along with the runtime status details within roughly 1-15s.
v0.319.0
- Cluster monitor events with information on the backing (Kubernetes) resources is
no longer gated behind unstable feature
cluster_monitor_resources(deprecated). It is now enabled by default. This change adds RBAC permissions to get the deployments of the API server and the runner. The status of the backing Kubernetes resources is shown in the Feldera Health page to every (authenticated) user. The cluster monitoring of resources can still be disabled by setting in the Helm chartdisableClusterMonitorResourcestotrue.
v0.316.0
- A bug fix introduced a backward incompatible change to the replay journal format. This only affects pipelines configured with exactly-once fault tolerance. Such pipelines should not be upgraded to the new Feldera runtime if they are in a failed state with non-empty replay journal. Upgrade is possible once the pipeline has been cleanly stopped without a failure.
v0.313.0
-
New DynamoDB output connector. It writes a SQL view to an Amazon DynamoDB table, mapping inserts and updates to upserts and deletes to deletes keyed by the table's primary key. See the connector documentation for configuration details.
-
Pipelines now have a
tagsfield: free-form labels for organizing and filtering pipelines, exposed across the API,fdaCLI, web console, and Python SDK (PipelineBuilder(tags=...),pipeline.modify(tags=...),pipeline.tags()). -
Editing only a pipeline's
descriptionortagsno longer bumps itsversionorrefresh_version, nor triggers recompilation. These fields can therefore be edited at any state of a pipeline (e.g. while running).
v0.311.0
- The default value of
max_output_buffer_size_recordsis now 10,000,000 instead of unbounded.
v0.309.0
-
Rust compiler will clean up the
targetdirectory automatically when its usage reaches the disk limit. This is currently behind the unstable feature flagrust_compiler_full_cleanup. -
Pipeline name is now limited to 63 characters and must follow the Kubernetes label pattern (and be non-empty and contain no dots as before). The check is only enforced when the pipeline is being newly created, its
namefield is being PATCHed or it is getting fully updated via PUT even if the name does not change. Otherwise, existing pipelines with a now invalid name will continue to function. This change is not backward compatible for scripts that create pipelines with names that are no longer valid, in which case they will now receive an error instead of succeeding. However, especially in the Kubernetes runner these pipelines would already not work.
v0.307.0
- Casts of strings to Boolean and floating point values will produce runtime errors instead of legal values for illegal string values. The set of strings that can be legally converted to Booleans has been changed.
v0.306.0
-
No longer allowed to edit
runtime_config.resources.storage_classif the pipeline storage is not cleared. -
Calling
/starton a pipeline that already failed to compile will directly return an error instead of the runner later on setting thedeployment_errorduring its check whether to proceed to provisioning. -
New
max_queued_bytessetting for input connectors. The default is 1,000 timesmax_queued_records, whether that is explicitly set or the default of 1,000,000. This is a change in behavior, since previously there was no byte limit. We believe that the new behavior is generally an improvement that will prevent using excessive memory or even running out of memory but, to restore the previous behavior, specify a large number formax_queued_bytes. -
Delta Lake output connector:
log_retention_duration and
enable_expired_log_cleanup config options to control transaction-log retention on newly created
tables.
Both are only applied at table creation ( i.e. new table or truncate mode ); against an existing table they are ignored. Defaults are unchanged (Delta Lake's own: 30 days, cleanup enabled).
The connector now logs a warning at startup when checkpoint_interval,
log_retention_duration, or enable_expired_log_cleanup in the connector config
differs from the existing table's metadata.
- Large Delta Lake, Iceberg scans (e.g. Delta CDC
ORDER BY) and ad-hoc queries now share a bounded memory pool and spill to disk under<storage>/datafusion-tmp/.
A new runtime_config.datafusion_memory_mb setting controls the pool size
(defaults to 5% of the pipeline's memory budget, capped at 2 GB).
v0.294.0
The HTTP egress API endpoint now accepts a connector configuration as the JSON body. This allows more control over connector configuration. For example:
curl -s -N -X POST 'http://127.0.0.1:8080/v0/pipelines/PIPELINE_NAME/egress/VIEW_NAME' --json '{"format": {"name": "json", "config": {"array": true}}}'
v0.292.0
Pipeline monitoring: Feldera now monitors and persists a pipeline's health.
Events are queryable via /v0/pipelines/[pipeline]/events?selector=[all|status]
and a specific event via /v0/pipelines/[pipeline]/events/[<event-id>|latest]?selector=[all|status].
All API clients support these endpoints. The Web Console will soon expose these
events via a tab too.
v0.289.0
API changes:
- (New) Details about the storage status is a new pipeline field:
storage_status_details. It does not get get cleared when the pipeline stops, only when the storage is cleared. - (Fix) Dedicated error
BootstrapPolicyImmutableUnlessStoppedfor repeated/startof a pipeline but with a different bootstrap policy. - (New) Recent per-endpoint connector error messages are now persisted in the pipeline
checkpoint and restored on resume, so debugging information survives a restart. The
/statsendpoint gains an opt-in?include_connector_errors=trueselector that inlines these messages alongside the counters; the default response is unchanged so hot pollers stay lightweight. The support bundle collector uses the selector automatically. - (Checkpoint format) Backwards-compatible extension:
CheckpointInputEndpointMetricsandCheckpointOutputEndpointMetricsgain optionalparse_errors/transport_errors/encode_errorsfields. Old checkpoints load as empty lists; checkpoints with no errors still serialize without the new keys, so unaffected files stay byte-identical.
CAST(variant AS VARCHAR) will return a meaningful value for all
scalar variant values, and not just for VARIANT objects with a
string value. In the past this cast used to return NULL.
(CAST(string AS VARIANT) AS type) will now behave like
CAST(string AS type). Previously the result was NULL.
Conversion of short intervals including seconds to strings will now include the fractional seconds as well. Previously the fractional seconds were ignored.
v0.288.0
Delta Lake input connector error handling behavior change:
In the past if the connector wasn't able to read a table version, it signaled an error and moved to the next version. This could cause data loss. With this change the connector will either retry forever or fail and stop producing input after exhausting retry attempts.
The second behavioral change is that the connector can now produce duplicate inputs even without a pipeline restart as the connector retries processing delta log entries.
Functions RLIKE and REPLACE_REGEXP will crash for invalid
regular expressions. Previously they treated such as expressions
as expressions which never match. The new behavior more closely
aligns with other databases.
v0.281.0
New dbt adapter for Feldera (dbt-feldera)
A new dbt adapter that lets you build streaming data pipelines using standard dbt workflows. Install from PyPI:
pip install dbt-feldera
Feldera's DBSP engine automatically incrementalizes every query, so incremental models
get true IVM without watermarks or manual merge logic.
Supported materializations: table, view, incremental, seed, and
streaming_pipeline.
See the README for configuration and usage details.
Starting a pipeline while storage is still clearing (storage_status=Clearing) now returns
CannotStartWhileClearingStorage instead of succeeding. Clearing storage while a start
is in progress but hasn't yet transitioned to Provisioning now returns
StorageStatusImmutableUnlessStopped instead of succeeding.
Backward-incompatible Delta Lake output connector change. The new max_retries setting configures
the number of times the connector retries failed Delta Lake operations like writing Parquet files
and committing transactions. The setting is unset by default, causing the connector to retry
indefinitely. This behavior prevents data loss due to transient or permanent write errors.
Checkpoint sync: read_bucket and checkpoint loading priority
The checkpoint sync configuration now supports a read_bucket field — a read-only
fallback bucket used to seed a pipeline's initial state. The pipeline never writes
to read_bucket.
Checkpoint sources are now resolved in priority order:
- Local checkpoint — if the pipeline already has a local checkpoint, it resumes from that without contacting any remote bucket.
bucket— the pipeline's own S3-compatible bucket. If a checkpoint is found here, it is used andread_bucketis ignored.read_bucket— consulted only when both local storage andbucketare empty. This allows a new pipeline to seed from another pipeline's checkpoint, avoiding a full backfill.read_bucketmust point to a different location thanbucket.
Refer to the checkpoint sync documentation for details.
NATS input connector retry and health check support
The NATS input connector now supports automatic reconnection with configurable retry behavior. Two new configuration fields have been added:
inactivity_timeout_secs: Maximum time in seconds to wait for the next message before running a stream/server health check.retry_interval_secs: Delay between automatic reconnect attempts while in retry mode.
The connector now supports pause and resume (start) lifecycle operations, validates replay and resume sequence bounds, and provides improved error messages during retries and health checks.
NATS input connector timeout and probe updates
- The default value for
inactivity_timeout_secshas been increased from10to60seconds. - Health probes now avoid duplicate JetStream stream-info requests, reducing API pressure during retry and recovery loops.
NATS retry classification during resume and replay validation has also been refined: transient failures while fetching JetStream stream metadata are now treated as retryable, while logical sequence-range validation failures remain fatal.
v0.278.0
Checkpoint sync: remote checkpoints older than v0.225.0 are no longer supported
Checkpoints pushed to object storage by a Feldera pipeline older than v0.225.0 can no longer be used with Feldera v0.278.0 or later. Remote checkpoints must be stored as zip archives; the legacy unzipped format is no longer accepted.
v0.263.0
Added connector error list to input/output connector stats. Input and output status endpoints now list up to 100 most recent transport, parser, and encoder errors of each type.
In addition, the openapi spec for both endpoints now specifies strongly typed return values
of type InputConnectorStatus and OutputConnectorStatus respectively.
v0.252.0
Python API removed ignore_deployment_error
The ignore_deployment_error parameter has been removed from the Python
pipeline.start() method. Instead, make use of the newly added dismiss_error parameter.
If you do not want the pipeline to start if there is a pre-existing deployment error,
you should call pipeline.start(dismiss_error=False). Otherwise call pipeline.start()
which is by default equivalent to pipeline.start(dismiss_error=True) (preserving
existing behavior). If the start results in an error occurring, the method will still
throw an error as before. A pipeline deployment error can now also be separately dismissed
using a dedicated endpoint and the corresponding client functions (e.g.,
pipeline.dismiss_error() for the Python client).
Kafka input connector synchronize_partitions option
The Kafka input connector has a new setting synchronize_partitions. When it is
set to true, the connector will read messages in order of their Kafka timestamps
across partitions. Refer to the documentation for more information.
0.227.0
Loading data from checkpoints made in earlier versions of feldera (0.226.0 and below) are not compatible with versions 0.227.0 and above. When upgrading to a version >=0.227, existing pipelines should be backfilled rather than starting from a previous checkpoint.
0.226.0
The Delta Lake connector's skip_unused_columns property has been deprecated. Use
table-level skip_unused_colums
instead.
0.201.0
Cluster monitoring: Feldera now monitors the control plane components (api-server,
kubernetes-runner and compiler-server) health and stores these as events in the
database. They are exposed via /v0/cluster/events and further details of a specific
event can be retrieved via /v0/cluster/events/[<id>|latest].
The /v0/cluster_healthz endpoint now returns the latest recorded event.
All API clients support these endpoints. The Web Console will soon expose these
events via a panel too.
It monitors both what the services report themselves, as well as the status of the
resources backing them. The resources monitoring feature is not yet stabilized,
but can already be activated by adding cluster_monitor_resources to the
Helm chart unstableFeatures array value. The kubernetes-runner, being responsible
for the monitoring, is configured with an additional RBAC permission needed for this
feature (see kubernetes-runner-rbac.yaml for changes).
0.188.0
Prometheus metrics output now also contains pipeline names with a "pipeline_name" label, in addition to the exist "pipeline" label, which still contains the pipeline UUID.
0.186.0
The Kafka input connector will now start reading partitions added to a topic upon resuming from a checkpoint. Previously, the pipeline would not start in this case. Please refer to the Kafka input connector documentation for details.
0.156.0
BACKWARD-INCOMPATIBLE PYTHON SDK CHANGES
- The
Pipeline.listenmethod can now only be called when the pipeline is running or paused. Previously it was possible to callPipeline.listenbefore starting the pipeline in order to guarantee that all outputs produced by the pipeline are captured by the listener. With the new API, you can achieve the same by starting the pipeline in a paused state usingPipeline.start_pausedand callingPipeline.listenbefore unpausing the pipeline usingPipeline.resume.