Sayonora

Sayonora

← Back to homeFerry plans the move to Postgres. Warp runs and governs workloads on Postgres. Ferry tells you how hard moving to Postgres will be; Warp keeps your application running while you do it.

01 ghcr.io/polygres26/ferry

Ferry

Tool for moving off Oracle/MySQL/MariaDB/SQL Server onto Postgres: assess how hard the migration is, launch and track the real data-movement run, and bridge your existing application to Postgres while you do it.

On this page

Two ways to get an assessment

Live and click-through, not a screenshot — try adding, favoriting, or browsing a connection yourself. Open full-screen →

What you get

Uploaded-report management, live — analyzed/not-analyzed status per file, the same view either data path lands you on. Open full-screen →

Where Ferry is still early: connection credentials are encrypted at rest (AES-256-GCM) when SAYONORA_ENCRYPTION_KEY is set, or resolved from Vault, CyberArk, AWS Secrets Manager, Azure Key Vault, or GCP Secret Manager instead of being stored at all — but that's opt-in, and a bare install without it stores a plain password, so set it (or use a secret reference) for anything beyond local dev. A second, read-only admin account and SSO login are both available (Enterprise) — see Free vs. Enterprise below; a bare-install free/Developer tier still has just the one shared admin account. Bandwidth/workload throttling, source production protection, and structured audit logging are also covered there.

Quick start:

docker run -p 8090:8090 \ -v polyadvisor-data:/data \ ghcr.io/polygres26/ferry:latest

Connecting, exploring, and reviewing PL/SQL with an LLM's help

A connection is a JDBC URL, a schema/user, and a credential — plain password today, or a reference into HashiCorp Vault, CyberArk, AWS Secrets Manager, Azure Key Vault, or GCP Secret Manager if you'd rather not store the secret in Ferry at all. Once it's saved, Objects lists everything that user can see, grouped by type and (for a multi-schema connection) owner-qualified so a package in one schema is never confused for one in another. Selecting a routine shows its real source, pulled live from the database, not a cached copy.

Ferry's add-connection form filled in with a name, an Oracle JDBC URL, a schema/user, and a masked password, with several credential-source options above the password field
Adding a connection: name, JDBC URL, schema/user, and a credential — stored as a plain password by default, or resolved at connect time instead of being stored at all. Six credential sources are supported: Vault, CyberArk, AWS Secrets Manager, Azure Key Vault, and GCP Secret Manager, alongside a plain password (this screenshot predates the three hyperscaler options; the toggle above the password field has six buttons today, not three).

What the LLM step actually does, precisely: select a package, procedure, or function and Ferry can ask an LLM to explain it — a plain-English summary of what it does, a bullet list of the specific constructs that are non-trivial to port to Postgres (cursor locking, DBMS_OUTPUT, autonomous transactions, and the like), and a trivial/moderate/substantial effort estimate with its reasoning. This is a reviewer's aid, not a code generator — it does not emit PL/pgSQL, and nothing it produces feeds back into the deterministic score above. Runs entirely local by default (no API key, nothing leaves the machine) against a small on-box model, or against an external provider if you configure one on the LLM page.

Ferry's Objects tab showing an Oracle stored procedure's real source code (a cursor FOR UPDATE loop, DBMS_OUTPUT, an audit-log insert, exception handling) and, below it, a live LLM-generated summary: what the procedure does, a list of non-trivial-to-port constructs, and a migration-effort estimate with reasoning
A real Oracle procedure's source (left: cursor FOR UPDATE loop, DBMS_OUTPUT, exception handling) and the LLM's live output below it — a summary, the specific constructs that need manual attention when porting to Postgres, and an effort estimate. Explanation and risk-flagging, not automated translation.

Admin console

Ferry's Findings tab for a connected MySQL database: two itemized migration findings, each with a severity badge (moderate, trivial) and a plain-English explanation of what it means for a Postgres port
The Findings tab against a real MySQL connection — each item found in the schema, its severity, and a plain-English explanation of what it actually means for the port. The same connection also has Objects (schema/routine browsing), Workload (captured query summary), and Parameters (full config inspection) tabs alongside this one.
Ferry's Sizing recommendation for the same connection: a SMALL tier with 2 vCPUs, 12 GB memory, 20 GB storage, 3,000 storage IOPS, and 100 max_connections, plus a caveats box and a rationale list explaining each number
Sizing recommendation for the same connection — a starting-point Postgres instance shape built from a fresh schema-size scan and workload capture, with the caveats and the line-by-line rationale behind every number shown alongside it, not hidden behind a tooltip.

The two screenshots above are the real product against a real connection. The embed below is the click-through demo — synthetic data standing in for a real connection, but the same console, every page explorable, nothing left as a static picture.

Sizing, live — vCPUs, memory, storage, IOPS, and the reasoning behind each number. Open full-screen →

Migration Service: launch and track a migration

Assessment tells you what you're dealing with; Migration Service is where you actually move the data — real, massively-parallel sayonora-migration runs (MongoDB change streams, MySQL binlog, SQL Server/Oracle native CDC, DynamoDB Streams, SQS, Neo4j snapshot, InfluxDB timestamp-cursor tail), launched from a form and tracked to completion, without ever leaving Ferry. Every write lands through Warp's own gRPC driver — never a direct JDBC connection to the target — so a migration in progress is subject to the exact same firewall, QoS, and cache pipeline as any other client.

sayonora-migration architecture: eight real source connectors -- MongoDB, MySQL, SQL Server, Oracle, DynamoDB, Amazon SQS, Neo4j, and InfluxDB -- each an initial parallel snapshot plus, where the source supports it, a live change-data-capture tail, coordinated by either Coordinator (one process, local thread pool, free tier runs serial) or DistributedCoordinator (a fleet of worker processes sharing a PartitionLeaseStore, Enterprise-licensed), landing through ResilientSink's retry-then-dead-letter path into WarpGrpcSink, which writes exclusively through Warp's own gRPC driver into the target Postgres. A CutoverReadinessChecker rolls partition completion, change-feed lag, dead-letter count, and row-level verification into a single ready/not-ready signal.
Every source connector feeds the same pipeline: parallel initial snapshot, then (where the source has one) a live change-data-capture tail owned by exactly one leader, retried and dead-lettered on failure, and written into Postgres exclusively through Warp's own gRPC driver. Local thread-pool parallelism is free; a distributed worker fleet sharing one lease store is the Enterprise tier. A readiness checker rolls partitions, lag, dead letters, and row-level verification into one go/no-go signal before you cut over.

Launch picks a connector, the target Postgres connection, and the source's own credentials, then starts the run server-side. Status shows the same live progress every worker process itself checkpoints against — partitions done, events applied, change-feed lag, and which worker currently owns the live tail — for every source pointed at that target, not just the one you just launched. Parallelism above 1 needs an Enterprise Warp license; without one, a migration still runs correctly, just serially, one partition at a time.

Sources Migration Service accepts

Every source gets a real, parallel initial snapshot. Where the source has a genuine change-tracking mechanism, Migration Service also runs a live change-data-capture (CDC) tail after the snapshot — not a polling re-scan. Where it doesn't (a queue; a graph database with no CDC in its free tier), that's stated plainly below, not glossed over.

SourceInitial snapshotLive CDCMechanism
MongoDB✓ parallelChange streams + resume tokens
MySQL✓ parallelBinary log, ROW format
SQL Server✓ parallelNative CDC (cdc.fn_cdc_get_all_changes_*)
Oracle✓ parallelLogMiner, SCN-checkpointed
DynamoDB✓ parallel scanDynamoDB Streams, shard-polled
Amazon SQSn/a — a queuen/aDrain-forward-delete, at-least-once (matches SQS's own guarantee)
Neo4j✓ parallelSnapshot only — Neo4j has no CDC outside Enterprise edition
InfluxDB✓ parallelTimestamp-cursor live tail

Every target schema is matched byte-for-byte to Warp's own wire protocol store, so a real client speaking that protocol can use the migrated data immediately.

Launch and Status, live — start a mock migration and watch it show up in both tabs. Open full-screen →

Pricing

Assessment — connect, score, size, browse, report — is unrestricted on every tier. What's paid is the parts of actually moving the data that scale past a single-process, single-migration setup: real parallelism, unattended cutover, and multi-tenant capacity. Same WARP_LICENSE_KEY as Warp — one key, one thing to buy.

Developer

$0 / forever

For evaluation, a real migration test, and one-migration-at-a-time production use.

  • Full assessment: compatibility analysis, feature inventory, Postgres sizing
  • Real data migration — snapshot + live CDC, every source connector
  • Automatic resume/checkpointing, data validation, progress monitoring
  • Encryption at rest, Vault/CyberArk secrets — opt-in, unrestricted
  • Source protection — a fixed default throughput cap, always on
  • Serial migration — one partition/table read at a time
  • One migration job running at a time
  • A failed row stops the run — no retry or dead-letter queue
  • No packaged cutover-readiness verdict or automatic cutover
  • Single shared admin account — no RBAC, audit log, or SSO
  • Community support

Enterprise

$7,500 / year, starting

Per migration environment. For production migrations run at real scale.

  • Everything in Developer, unrestricted
  • Parallel snapshot/partition workers, single process
  • A distributed worker fleet — real, multi-process parallelism
  • Failed-row retry with dead-letter queue
  • Cutover-readiness verdict, plus automatic cutover the instant it's ready
  • Configurable throughput cap, tuned to your source, not just the default
  • No fixed cap on concurrent migrations
  • Audit log, a second read-only account, SSO bearer-token login
  • Enterprise support

Schedule a Warp Architecture Review →

Full row-by-row capability breakdown, including exactly which real license check backs each row: Ferry capability table →

Free vs. Enterprise

Assessment (the whole first half of this page — connect, score, size, browse, report) is unrestricted on every tier. What's paid is the parts of actually MOVING the data that scale past a single-process, single-migration setup: real parallelism, unattended operation, and multi-tenant capacity. Reuses the same WARP_LICENSE_KEY as Warp itself — one key, one thing to buy.

CapabilityDeveloper / FreeEnterprise
Migration assessment
Compatibility analysis
Target Postgres sizing
Schema conversion
Data migration
Single-stream snapshot
Parallel snapshot workers †
Parallel table/partition migration †
CDC (live change-feed tail)
Automatic resume/checkpointing
Failed-row retry / DLQ †
Data validation / reconciliation
Cutover-readiness check †
Automatic cutover at the right time †
Migration progress monitoring
Bandwidth / workload throttling †Fixed defaultConfigurable
Source production protection †✓ (fixed default cap)✓ (tunable)
Multiple migrations concurrently †1No fixed cap
HA migration workers †
Encryption / enterprise secrets✓ (opt-in)✓ (opt-in)
Audit logging †
RBAC (second, read-only account) †
SSO (bearer-token login) †
SupportCommunityEnterprise

enforced today by a real license gate in sayonora-migration or Ferry itself — not a marketing line, a check that actually throws, clamps, or degrades when it's not licensed. Bandwidth throttling and source protection are the same mechanism (a token-bucket rate limiter on the write path, which backpressures the read side too): free tier always runs at a fixed default cap that protects the source without needing to be tuned; Enterprise can raise, lower, or effectively disable it. Encryption at rest (AES-256-GCM) and every secret-reference source (Vault, CyberArk, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) are real and unrestricted on every tier — opt-in via SAYONORA_ENCRYPTION_KEY or a secret reference, not something a license key changes. Audit logging, the second read-only account, and SSO bearer-token login are genuinely new capabilities, Enterprise-only, and inert (not merely hidden) on the free/Developer tier. Everything else runs identically regardless of license — CDC, validation, progress monitoring, and resumable checkpointing all work the same way whether or not a WARP_LICENSE_KEY is set.

The full console, starting from sign-in — every section above lives inside this one app. Open full-screen →