Operations & Reliability
Moving From Apache Flink 1.20 to 2.x: API, Configuration and State Planning
Flink 2.x removed APIs and changed configuration and serialization. Plan the move from 1.20 job by job, with state as the main decision.
What this article covers
Apache Flink 1.20 (LTS label) and the 2.0, 2.1, 2.2 and 2.3 lines, as listed on the Flink downloads page and in the 2.0 and 2.3 release documentation on 2026-10-26. Self-managed open-source Flink; managed services may differ.

Apache Flink 2.0 was released on 24 March 2025, and Flink 2.3.0 followed on 25 June 2026. Many production jobs still run on the 1.20 line, which the Flink website labels LTS. Moving them to 2.x is not a routine minor upgrade. The 2.0 release removed APIs, replaced the configuration file and changed serialization, and the project does not promise that 1.x state will restore on 2.x.
This article sets out where each release line stands on 26 October 2026, what changed in 2.0 that affects existing jobs, and how to plan the move job by job, with state as the main decision.
Where the release lines stand on 26 October 2026
The Apache Flink downloads page lists the releases below. Its update policy says the community supports the current and the previous minor release with bugfixes for critical issues. Since March 2023, when a new minor version is released, the line that loses support gets one final bugfix release. Bugfix releases for older lines can be requested on the developer mailing list.
| Line | Latest release on the downloads page | Status |
|---|---|---|
| 2.3 | 2.3.0, 25 June 2026 | Latest stable release (current minor) |
| 2.2 | 2.2.1, 15 May 2026 | Previous minor release |
| 2.1 | 2.1.3, 14 June 2026 | Older 2.x line |
| 2.0 | 2.0.2, 11 May 2026 | Older 2.x line |
| 1.20 | 1.20.5, 3 June 2026 | Labeled “Flink 1.20 (LTS)” in the site’s documentation menu |
| 1.19 | 1.19.3, 10 July 2025 | Outside the update policy |
The LTS label for 1.20 comes with no published end date on flink.apache.org. FLIP-458 proposed that the last 1.x line receive only bug fixes and security updates for a fixed term of two years. The wiki page does not show the vote result or name a start date, so treat it as background, not as a date to plan around. Security reports for all lines go through the process on the Flink security page, and fixes follow the community’s timeline.
The practical reading is simple. The 1.20 line still receives patch releases, but it receives no new features, and every new feature lands on 2.x. A plan that starts now leaves room to test before any 1.20 support ends.
What Flink 2.0 changed for existing jobs
The 2.0 release announcement and the 2.0 release notes list the breaking changes. These are the ones that most often affect production jobs.
- Removed APIs. The DataSet API, the Scala DataStream and DataSet APIs,
SourceFunction,SinkFunction, Sink V1 and the legacyTableSourceandTableSinkare gone. Jobs built on them need code changes before they compile against 2.x. - Configuration file.
flink-conf.yamland its parser were removed. Clusters and job submissions must use the standard-YAMLconfig.yaml. The release notes point to a migration tool, documented in the deployment configuration pages, that converts the old file. Options deprecated long enough were also removed. - Deployment mode. Per-job mode was removed in favor of application mode. The SQL Gateway gained application mode support as the replacement path for SQL jobs.
- Java. Java 8 support was dropped. The release notes make Java 11 the minimum and Java 17 the default and recommended version, with Java 21 supported. Check the documentation of your target release before choosing a runtime.
- State backends. The
FsStateBackendandMemoryStateBackendclasses were removed. Jobs that configure them by class name need updating. - Serialization. Kryo was upgraded to version 5.6, and built-in serializers for Map, List and Set are now enabled by default.
- Local recovery. With the Adaptive Scheduler, local recovery now needs explicit opt-in through
execution.state-recovery.from-local, which defaults to false.
Later 2.x releases add their own behavior changes. The 2.3.0 announcement notes two. Queries whose upsert key differs from the primary key now fail at planning time unless an ON CONFLICT strategy is set. Watermark alignment also uses a buffer by default, and setting pipeline.watermark-alignment.buffer-size to 0 restores the 2.2 behavior. Read the release notes for every minor version between your current and target release, not only the target.
State is the central decision
The 2.0 release notes say plainly that state compatibility between 1.x and 2.x is not assured. The upgrading guide for 2.3 keeps a savepoint compatibility table, but its rows cover savepoints taken on 1.8 to 1.20 and restored on 1.x releases. It has no 1.x-to-2.x entry. The guide also states that major upgrades can break both source and binary compatibility, even for Public APIs.
The serializer changes explain much of the risk. State written with Kryo 2 serializers, or with the older handling of collection types, may not read back under the 2.x defaults. Managed services say the same: the Amazon Managed Service for Apache Flink 2.3 page calls an upgrade from 1.x a major version upgrade with breaking changes and state compatibility considerations.
So each stateful job needs one of three outcomes, decided before the upgrade window:
| Outcome | When it fits | What it costs |
|---|---|---|
| Restore from a 1.20 savepoint | A test restore on the target version succeeds, and output matches a reference run | Test effort; the result holds only for the state types and serializers you tested |
| Rebuild state from sources | Sources keep enough history to replay, for example retained event streams or a change log | Replay time and load on sources; output during the rebuild must be handled |
| Redesign the job | The job uses removed APIs heavily, or its state model needs to change anyway | Engineering effort; treated like a new job with a parallel run |
Stateless jobs, and jobs whose state is short-lived, are usually the easiest. They can often be restarted on 2.x from their sources without a savepoint at all. Do that inventory first; it shrinks the hard part of the plan.
A job-by-job upgrade procedure
- Inventory. For each job, record the APIs used, the connectors and their versions, the state backend, the state size, the serializers for state types, the deployment mode and the Java version.
- Check connectors. Connectors are released separately. On the downloads page, the Kafka connector 5.0.0 lists Flink 2.1.x and 2.2.x, while 3.4.0 lists 1.20.x. Confirm that every connector you use has a release for your target Flink version before you pick that target.
- Convert configuration. Convert
flink-conf.yamltoconfig.yamlwith the documented tool, then review removed and renamed options by hand. - Port the code. Replace removed APIs, move per-job submissions to application mode and build against the target Java version.
- Prove state handling. Set explicit operator IDs with
uid()on 1.20 first, then take a savepoint. Restore it on the target version in a test environment and compare output with a reference run. If it fails, choose a rebuild or a redesign. - Run in parallel. Where sources allow, run the 2.x job beside the 1.20 job and reconcile results with agreed checks before switching consumers.
- Cut over with a rollback point. Keep the 1.20 job and its last savepoint until the 2.x job has run cleanly through a full business cycle.
The upgrading guide describes two cluster approaches: an in-place upgrade, and a shadow copy where the new version runs beside the old one. For a major version change, the shadow copy keeps the rollback path simpler.
Choosing a target: 2.2 or 2.3
Under the update policy, both 2.3 and 2.2 receive critical bugfixes on 26 October 2026. When the next minor release ships, 2.2 will drop out and get one final bugfix release. Teams that want the longest runway on one line should usually target 2.3, if their connectors support it. Teams whose connectors list only 2.2 can move to 2.2 first and plan a smaller minor upgrade later.
Two features deserve care when you choose. The ForSt state backend, introduced for disaggregated state in 2.0, is still marked experimental in the state backends documentation. That page says it is not fully available for production and does not support canonical savepoints. Keep production jobs on the heap-based or RocksDB backends unless your own tests justify a change. The DataStream V2 API was also introduced as experimental in 2.0, so new jobs should not depend on it without the same testing.
Managed services can differ from open-source Flink. The AWS 2.3 page lists open-source 2.3 features that its service does not support, including materialized tables and the ForSt backend, and it keeps its own watermark alignment default. If part of your estate runs on a managed service, plan against that provider’s documentation as well.
Operations checks after the move
- Checkpoint duration, size and failure counts compared with the 1.20 baseline.
- Backpressure and consumer lag on the jobs that changed connectors.
- Restart behavior, including whether local recovery is enabled as intended.
- JobManager high availability still works on the new version, through Kubernetes or ZooKeeper services as described in the high availability documentation.
- Savepoints taken on the new version restore cleanly, as a drill rather than an assumption.
These checks belong in your runbooks, not only in the upgrade project. Our platform reliability work uses the same drill approach for recovery objectives.
How Bassirah can help
Bassirah provides independent engineering for self-managed Apache Flink, including 1.20-to-2.x upgrade assessments, state planning and rehearsed cutovers. We are not a partner of Ververica, Confluent or Amazon Web Services, and upstream fixes follow the community’s timeline, as our open-source support model explains. See our Apache Flink engineering page for scope.
Independent engineering services
These are independent Bassirah engineering and support offerings. They do not imply upstream vendor or foundation endorsement, official vendor support rights, enterprise feature entitlement or maintenance guarantees.
Sources
- Apache Flink downloads and update policy
- Apache Flink 2.0.0 release announcement
- Release notes - Flink 2.0
- Apache Flink 2.3.0 release announcement
- Upgrading Applications and Flink Versions (Flink 2.3 docs)
- State Backends (Flink 2.3 docs)
- High Availability (Flink 2.3 docs)
- FLIP-458: Long-Term Support for the Final Release of Apache Flink 1.x Line
- Security (Apache Flink)
- Amazon Managed Service for Apache Flink 2.3
Related pages
More insights
Operations & Reliability
Moving Metabase From H2 to PostgreSQL: A Production Setup Runbook
Metabase stores its questions and dashboards in an application database. How to move it from H2 to PostgreSQL safely, then upgrade.
Metabase
Read article : Moving Metabase From H2 to PostgreSQL: A Production Setup Runbook→
Comparisons & Decisions
Moving a PostgreSQL Application to YugabyteDB: Compatibility Testing and Migration Planning
YSQL reuses the PostgreSQL query layer, but it is not a drop-in replacement. How to test compatibility, redesign the schema and choose a migration route.
PostgreSQLYugabyteDB
Architecture Patterns
YugabyteDB Multi-Region Topologies: Synchronous Replication, xCluster or Read Replicas
Synchronous replication, geo-partitioning, xCluster and read replicas solve different problems. What each does, what it costs and how to choose.
YugabyteDB
Discuss This With an Architect
Map these trade-offs against your workloads, constraints and operating model.

