Oracle7 min read
Migrating Oracle Partitioned Tables to PostgreSQL
Partitioned tables are where a lot of Oracle migrations slow down — not because PostgreSQL lacks partitioning (it has mature declarative partitioning) but because the two differ in a few places that quietly break assumptions. This guide maps every Oracle partition type to its PostgreSQL form: RANGE and LIST are direct matches, HASH uses MODULUS/REMAINDER instead of a count, composite becomes nested sub-partitioning, interval partitioning has no native equivalent (use a DEFAULT partition plus pg_partman or a scheduled job to pre-create), and reference partitioning is rebuilt by carrying the parent key onto the child. It shows the two-part DDL (parent declares PARTITION BY, each child declares its bounds) and a DEFAULT catch-all so an out-of-range insert doesn't fail. Then the gotchas that bite: PostgreSQL has no global indexes — indexes on a partitioned table are local, so a primary key or unique constraint must include the partition key, which breaks an Oracle global unique index on a non-key column; partition-wise joins are off by default (enable_partitionwise_join); and ATTACH/DETACH PARTITION replaces Oracle's partition exchange. PostgreSQL 19 adds in-place MERGE and SPLIT PARTITIONS, closing one of the last maintenance gaps.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL 19: New Features and How to Use Them
PostgreSQL 19 reached Beta 2 in July 2026, with general availability expected around September–October 2026 — and it's a landmark release that lands right on the pain points Oracle DBAs feel moving to PostgreSQL. The headline is pg_plan_advice: an extension that finally lets you stabilize and steer planner decisions in core PostgreSQL, the closest thing yet to the optimizer control Oracle DBAs reach for (with a pg_stash_advice companion to re-apply saved advice by query id). Native REPACK — and non-blocking REPACK CONCURRENTLY — brings online table rebuild and bloat removal into core, no more reaching for the pg_repack extension. Parallel autovacuum (autovacuum_max_parallel_workers) keeps maintenance ahead on the huge tables a migration produces. Logical replication now replicates sequence values, closing the classic cutover gap where every sequence had to be re-synced by hand. Plus quick wins: ON CONFLICT DO SELECT for atomic get-or-create, MERGE/SPLIT PARTITIONS in place, online data-checksum toggling, LZ4 TOAST by default, and JIT off by default. The honest caveat: beta is for testing, not production — target the current stable release for live systems and use the beta to rehearse your cutover.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL Join Tuning for Oracle DBAs
PostgreSQL has the same three join algorithms Oracle does — nested loop, hash join, merge join — so the mechanics feel familiar. What changes for an Oracle DBA is the philosophy of control: core PostgreSQL has no optimizer hints, so you tune a join by fixing the inputs the planner reasons about, not by overriding its decision. This guide walks the four levers that fix almost every slow join. Statistics come first — a bad join is usually a bad row-count estimate (the planner expected 10 rows and got 10 million), fixed by keeping ANALYZE current and using CREATE STATISTICS for correlated columns. Then work_mem: hash builds and merge sorts spill to disk when they exceed it (watch for Batches > 1 or Disk: in EXPLAIN ANALYZE), so raise it per-query, never globally. Then indexes — a B-tree on the join key enables efficient nested loops and sort-free merges, and PostgreSQL notably does NOT auto-index foreign-key columns, so indexing the FKs you join on is often the single biggest win after a migration. Finally, read the plan with EXPLAIN (ANALYZE, BUFFERS), use the enable_* switches only to diagnose, and reach for join_collapse_limit on complex many-table queries. The mindset shift: when the plan is wrong, an input is wrong — fix that, and the planner keeps choosing well as your data changes, which a frozen hint never would.
Rakesh Mamidala
Founder & Lead Engineer
Product6 min read
July Recap: PostgreSQL Skills Every Oracle DBA Needs
A month of writing about PostgreSQL platforms, performance, and operations keeps returning to one point: for an Oracle DBA, the SQL syntax is rarely what makes a migration hard — the real shift is operational. This recap distills the skills that carry the most weight, each mapped from the Oracle concept you already know. Read pg_stat_statements and EXPLAIN (ANALYZE, BUFFERS) the way you read AWR and ASH. Think in MVCC, VACUUM, and bloat instead of undo and redo. Translate Data Guard to streaming replication (often with Patroni), RMAN to pgBackRest, and a logical standby to logical replication for zero-downtime cutover. Tune shared_buffers, work_mem, and autovacuum rather than the SGA and PGA. And know the ecosystem — RDS, Aurora, Cloud SQL, AlloyDB, Azure Flexible Server, Neon, Supabase — because they all run standard PostgreSQL, so learning the engine once keeps every one of them open. That portability is, in the end, the strongest argument for the move.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL 17: What's New and Why It Matters for Migration
When you're moving off Oracle, the PostgreSQL version you target isn't a detail — newer releases keep closing the exact gaps that make Oracle migrations hard, and PostgreSQL 17 is a strong target for that reason. JSON_TABLE, the standout of its SQL/JSON additions, turns JSON into relational rows inline in a query — the natural landing spot for Oracle XMLTABLE and JSON-in-the-database patterns — and the new JSON constructors map a lot of document logic that used to need a manual rewrite onto portable standard SQL. Logical replication becomes cutover-grade: slots survive a failover, and pg_createsubscriber converts a physical standby into a logical subscriber in place, cutting risk in the highest-stakes migration phase. Maintenance gets lighter too — a new memory structure makes autovacuum far leaner on large tables, pg_basebackup gains incremental backup via WAL summarization, sequential scans read faster with streaming I/O, and MERGE now supports RETURNING and updates through views. For a new migration, targeting the current major buys the JSON and replication wins for free and the longest support runway — just confirm your managed provider offers 17 in your region and edition first.
Rakesh Mamidala
Founder & Lead Engineer
Oracle7 min read
Migrating from Oracle Exadata to PostgreSQL
Migrating from Oracle Exadata to PostgreSQL is a different exercise from a plain Oracle-to-PostgreSQL move, and the difference is hardware. Exadata is Oracle Database on an engineered system whose storage tier does real database work — Smart Scan pushes filtering and projection down to the storage cells, storage indexes skip regions that can't match a predicate, Hybrid Columnar Compression shrinks warehouse tables, and flash cache plus a fast interconnect deliver NVMe-class latency. PostgreSQL has no smart storage cell; it reads blocks and filters in the engine. The migration mindset, then, is to reproduce each Exadata effect with a PostgreSQL technique: declarative partitioning and BRIN indexes to replace Smart Scan and storage indexes, TOAST or columnar-extension compression in place of HCC, parallel query for big scans and joins, and NVMe storage with a generous shared_buffers to close the raw-latency gap. Size the target from real uncompressed row sizes rather than the HCC-flattered Exadata number. The conversion mechanics — schema, DDL, PL/SQL, bulk load, validation, CDC cutover — are the standard pipeline; Exadata just raises the bar on the target design, so plan the performance parity up front.
Rakesh Mamidala
Founder & Lead Engineer
Business7 min read
Cost Comparison: Oracle Cloud vs PostgreSQL on AWS
A useful database cost comparison isn't 'which is cheaper' — it's understanding how each pricing model is structured so you can map it to your own workload and get an honest number. Both Oracle Cloud and PostgreSQL on AWS are production-grade homes for a database; they simply meter cost along different axes. This piece breaks a database bill into its real components — compute, storage and IOPS, software/edition, HA and replicas, data transfer, and operational effort — and shows where the models genuinely differ: the software line. A commercial engine is licensed by processor or user, often with separately licensed options and a BYOL-vs-license-included choice on Oracle Cloud; open-source PostgreSQL on AWS has no software license line at all, with every feature folded into one engine. It closes with the common estimation pitfalls (comparing on-demand to on-demand, forgetting non-prod, ignoring operational cost) and a fair method: model the same workload twice with the purchasing model you'd actually commit to, add migration and operational cost as explicit line items, and look at a three-to-five-year total.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Neon, Supabase, Tembo: The New PostgreSQL Platforms
The big-cloud managed services aren't the only game anymore. A wave of PostgreSQL-native platforms has rethought what a database service can be, and even if you don't adopt one today they signal where the ecosystem is heading: serverless, developer-first, and built entirely on open Postgres. Neon separates compute from storage to scale to zero and adds copy-on-write database branching, so every pull request can have its own throwaway database. Supabase wraps a real PostgreSQL database in an application backend — auto-generated APIs, auth, storage, realtime — leaning on Postgres primitives like row-level security, and it's open source and self-hostable. Tembo bets that Postgres's extension ecosystem can replace a shelf of specialized databases, packaging curated stacks for vector search, queues, and OLAP. For a core Oracle workload the mature managed services are still the conservative landing zone, but because every one of these runs standard PostgreSQL, migrating off Oracle once keeps all of them open to you later.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL on Google Cloud SQL: Enterprise Readiness
Google Cloud gives you two managed PostgreSQL options, and knowing which is which saves a lot of confusion: Cloud SQL for PostgreSQL is the mainstream managed service — the peer of RDS and Azure Flexible Server — while AlloyDB is Google's PostgreSQL-compatible, performance-tuned engine, its answer to Aurora. This article covers Cloud SQL, the right default. It's enterprise-ready with eyes open: HA with automatic failover, automated backups and point-in-time recovery, in-region and cross-region read replicas, an Enterprise Plus edition with a data cache, IAM database authentication, and real community PostgreSQL so your SQL and data stay portable. Going in, know the managed-service limits (no superuser, a curated extension list), plan maintenance windows, use the Cloud SQL Auth Proxy plus a pooler for bursty apps, and evaluate AlloyDB only when very large or very hot workloads outgrow Cloud SQL. If your data platform already lives on Google Cloud, Cloud SQL slots in with the least friction — though it still doesn't perform the Oracle-to-PostgreSQL conversion for you.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Aurora PostgreSQL vs RDS PostgreSQL: When to Use Each
Both are PostgreSQL on AWS and both speak the same SQL, so the difference isn't what you write — it's what runs underneath. RDS PostgreSQL is community PostgreSQL on EBS storage; Aurora PostgreSQL is PostgreSQL-compatible, keeping the query engine but replacing the storage layer with a distributed, log-structured system. That one change is the whole story. Aurora's storage buys six-way replication across three AZs, up to 15 fast/cheap read replicas that share one volume, seconds-level failover, auto-growing storage, and backtrack plus fast clones — genuinely better for read-heavy, replica-hungry workloads. RDS keeps 100% community PostgreSQL (zero engine lock-in), often lower cost for steady single-writer workloads, a simpler mental model, and the newest PostgreSQL versions first. The article gives a decision table and an honest take on Aurora's soft lock-in: your SQL and data move cleanly, but backtrack, fast clones, and the storage behaviour are Aurora-only. The pragmatic path for most Oracle migrations: start on RDS, prove the workload, move to Aurora only when read-scaling or failover clearly justify it.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL on Azure: What Works and What Doesn't
Azure's PostgreSQL story used to be confusing — two products with similar names — but that's over: the one to build on is Azure Database for PostgreSQL Flexible Server, since Single Server is on a retirement path. What works well: zone-redundant HA with automatic failover, stop/start compute that lets you pause non-prod and stop paying for compute (cleaner than RDS, great for dev/test), broad server-parameter control with a decent extension list (PostGIS, pg_stat_statements, pgvector), native Entra ID authentication for Microsoft-stack enterprises, and the same community PostgreSQL so your SQL and data stay portable. What to watch: read replicas have historically been less flexible than on AWS, the usual managed-service limits (no superuser, approved-extensions-only), connection limits that make pooling essential (a built-in PgBouncer you must enable and size), and built-in migration tooling that's strong for Postgres-to-Postgres but not for heterogeneous Oracle conversion. If your organisation is already deep in Microsoft, Flexible Server removes weeks of friction — the migration itself stays a separate workstream.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL on AWS RDS vs Self-Managed: The Trade-offs
When your Oracle database lands on PostgreSQL, the next decision is where it runs: a managed service like Amazon RDS, or PostgreSQL you install and run yourself. People frame this as a cost debate, but the honest framing is control vs. operational burden. RDS handles automated backups and PITR, Multi-AZ failover, minor-version patching, read replicas, and monitoring — for a small team that's a full-time DBA's worth of undifferentiated work, and that's the real value, not the instance price. What you give up: no superuser or OS shell, only approved extensions, and parameter groups instead of direct postgresql.conf access. Self-managed wins when you need extensions RDS doesn't allow, have real DBA depth in-house, face data-residency constraints, or run at a scale where a self-managed fleet on reserved instances undercuts RDS. The honest default for most teams leaving Oracle: start on RDS, and move to self-managed only when you hit a concrete wall it can't clear. Because RDS runs community PostgreSQL, your data and SQL stay fully portable either way.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL WAL: What Every DBA Must Understand
If you understand one internal subsystem in PostgreSQL, make it the Write-Ahead Log. Durability, crash recovery, replication, point-in-time restore, and streaming replicas are all built on it — and for an Oracle DBA it maps almost exactly onto redo logs. The rule is in the name: before any change reaches a data file, it's written to the log first, so a commit is fast and a crash is survivable by replaying WAL from the last checkpoint. WAL is written in 16 MB segments under pg_wal, and position is tracked by an LSN — the equivalent of Oracle's SCN and the currency of replication. This guide draws the full Oracle translation (redo→WAL, SCN→LSN, Data Guard→streaming replication, LogMiner→logical decoding), explains checkpoints and the max_wal_size / checkpoint_timeout knobs, covers WAL archiving for point-in-time recovery, and gives practical tuning: wal_compression, the right wal_level, putting pg_wal on fast storage, and watching replication slots so an abandoned slot doesn't fill your disk.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL6 min read
Autovacuum Tuning: Stop It From Slowing You Down
Almost every 'PostgreSQL got slow' story after an Oracle migration traces back to one subsystem with no Oracle equivalent: autovacuum. The instinct is to blame it or turn it off — don't. When it seems to be slowing you down, the fix is almost always to let it run more often, not less. Because PostgreSQL uses MVCC, every UPDATE or DELETE leaves a dead tuple behind, and autovacuum is what reclaims that space and refreshes planner statistics; neglect it and tables bloat while plans drift. The classic trap is the default 0.2 scale factor, which makes a big table wait for millions of dead rows before it's touched, so it runs rarely, long, and hard. This guide gives the two changes that fix most problems — lower the scale factor to a fixed row threshold on large tables, and raise the cost limit so vacuum finishes in minutes on SSDs — plus the non-negotiable one: watching transaction-ID wraparound so the database never shuts down to protect itself. Tune from evidence in pg_stat_user_tables, not by guessing.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL Upgrade Strategies: In-Place vs pg_upgrade vs Migration
A PostgreSQL major-version upgrade changes the on-disk format, so — unlike an Oracle patch — you can't just swap binaries and restart. There are three real paths, and picking the wrong one either costs you a long maintenance window or a lot of unnecessary risk. dump/restore is the simplest and most portable, but re-inserts every row and rebuilds every index, so it's only practical for small databases. pg_upgrade is the in-place workhorse: in --link mode it hard-links the data files instead of copying them, cutting a big-database upgrade to minutes of downtime. Logical replication is the near-zero-downtime option: stand up the new major version as a subscriber, let it catch up, and cut over in seconds — the same technique used for migrations. This guide walks each path, the prerequisites that bite (extensions must exist on the new cluster, statistics are NOT carried over so you must ANALYZE afterward), and a simple decision rule based on your database size and downtime tolerance. Minor-version updates, by contrast, are just a binary swap and restart.
Rakesh Mamidala
Founder & Lead Engineer
Migration8 min read
Best Oracle to PostgreSQL Migration Tools in 2026
There's no single 'best' Oracle to PostgreSQL migration tool — there's the best one for your schema, your downtime tolerance, and your team. This honest roundup covers the real options in 2026 and what each is genuinely good at: Ora2Pg (the mature, free, open-source workhorse for schema and data export), AWS DMS + SCT (managed replication and conversion for teams committed to AWS), the EDB migration tooling (commercial, enterprise support), the built-in extensions and FDWs for DIY moves, and DBMigrateAIPro (an integrated assess-plan-migrate-verify flow with automated PL/SQL transpilation, cryptographic validation, built-in CDC cutover, and a relational-to-MongoDB path). Rather than crown a winner, it gives you a decision framework — assess your PL/SQL surface, your cutover window, and how much you need to prove the migration was lossless — so you can match the tool to the job instead of the marketing.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL8 min read
PostgreSQL Streaming Replication: Zero to Production
Streaming replication is the foundation everything else in PostgreSQL HA sits on — read replicas, automatic failover, and near-zero-downtime maintenance all build on it. It ships the primary's write-ahead log to one or more standbys in real time; each standby is a byte-exact, read-only hot standby that can also serve read queries. This guide takes it from zero to production: the primary settings (wal_level = replica, max_wal_senders, a REPLICATION role), seeding a standby with pg_basebackup and standby.signal, and the choice that defines your durability/latency trade-off — asynchronous (fast, can lose the last few transactions on failover) vs synchronous replication (synchronous_standby_names, no data loss, higher commit latency). It covers replication slots so a lagging standby never causes the primary to delete WAL it still needs, monitoring lag through pg_stat_replication, and cascading replicas. For Oracle DBAs it's the physical-standby story you know from Data Guard — and it's the layer Patroni automates for real failover.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
pgBackRest: Enterprise Backup for PostgreSQL
pg_dump is a logical snapshot, not a disaster-recovery strategy — for real DR of a large PostgreSQL database you want physical backups plus point-in-time recovery, and pgBackRest is the tool that does it properly. Think of it as PostgreSQL's RMAN: full, differential and incremental backups; parallel, compressed and optionally encrypted; a repository that can live on local disk or S3/Azure/GCS; WAL archiving for PITR; backup verification with checksums; and delta restore that only copies changed files. This guide covers the concepts an Oracle DBA needs to map RMAN onto pgBackRest — the stanza, the archive_command that ships WAL, the full/differential/incremental backup types and how they chain, retention policies, and a recovery to a specific point in time. It also explains why pgBackRest beats a hand-rolled pg_basebackup script (incrementals, parallelism, repo management, verification) and where it fits alongside logical dumps for migrations and single-table restores.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL8 min read
High Availability with Patroni: The PostgreSQL HA Standard
Oracle DBAs come to PostgreSQL expecting Data Guard or RAC and find… neither, exactly. PostgreSQL's core ships streaming replication but not automatic failover — promoting a standby when the primary dies, without split-brain, is an orchestration problem, and Patroni is the de facto standard that solves it. This guide explains the architecture: a Patroni agent on each node, a distributed consensus store (etcd/Consul/ZooKeeper) that holds the leader lease and elects a new primary, and a routing layer (HAProxy against Patroni's REST health endpoints, or a VIP) that always points clients at the current primary. It covers how Patroni prevents split-brain through the DCS leader lease, synchronous vs asynchronous modes and what each means for failover data loss, using pg_rewind to rejoin a failed primary as a standby without a full rebuild, and how this compares to Data Guard (failover, not shared-storage clustering — PostgreSQL is shared-nothing, so there's no RAC equivalent, and that's usually fine). It's the answer to 'how do we get Data-Guard-level HA on PostgreSQL.'
Rakesh Mamidala
Founder & Lead Engineer
Migration9 min read
Migrating Oracle to MongoDB: Turning Foreign Keys into Embedded Documents
Almost every migration tool goes one direction — relational to relational, usually to PostgreSQL. Going relational → MongoDB is the harder, under-served path, and the naive version (copy each table to a collection) isn't a document model at all — it's SQL with extra steps, joined by hand with $lookup on every read. This post covers doing it properly: loading each row as a TYPED BSON document (NUMBER(p,s) → exact Decimal128, not a lossy float; dates → datetimes; BLOB → Binary; NULL → null, not "null"), rebuilding your primary and unique keys as MongoDB indexes, count-validating every collection, and then the interesting part — folding 1:N child tables into their parent as embedded arrays, auto-detected from the source's foreign keys. It also covers the traps that quietly wreck this migration: why junction/M:N tables must NOT embed (they'd double-count), how the 16MB BSON document limit is handled without crashing, what happens to a child row with a dangling foreign key (kept as an orphan, never duplicated, never dropped), and why Oracle's hidden function-based-index columns must be skipped. The result is a database shaped the way MongoDB is meant to be queried — with the counts to prove nothing was lost.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Window Functions in PostgreSQL vs Oracle: Same Power, Better SQL
Window functions are one of the smoothest parts of an Oracle→PostgreSQL migration: ROW_NUMBER, RANK, DENSE_RANK, NTILE, LAG, LEAD, FIRST_VALUE and the running-total OVER (PARTITION BY … ORDER BY …) syntax port almost verbatim. But 'almost' is where migrations break. Three things bite: the LAST_VALUE frame trap (both databases default the window frame to RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, so LAST_VALUE quietly returns the current row, not the last — the fix is an explicit ROWS BETWEEN … UNBOUNDED FOLLOWING frame); Oracle's KEEP (DENSE_RANK FIRST/LAST ORDER BY …) aggregate, which has no direct PostgreSQL equivalent and must be rewritten with a window function or DISTINCT ON; and IGNORE NULLS on LAG/LEAD/FIRST_VALUE, which Oracle has had for years and PostgreSQL only gained natively in version 17 (before that you need a workaround). This post walks the 90% that just works, then each difference with the exact rewrite — plus RATIO_TO_REPORT and the WINDOW clause that makes the PostgreSQL version genuinely cleaner to read.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL6 min read
Generated Columns in PostgreSQL: Replacing Oracle Virtual Columns
Oracle virtual columns and PostgreSQL generated columns look like the same feature — a column defined by an expression over other columns — but they differ on the one axis that matters for migration: storage. Oracle's are VIRTUAL by default (computed on read, zero disk); PostgreSQL only offers STORED generated columns (computed on write, they take disk space). So a straight port turns a free virtual column into a stored one, growing your table. This post covers the clean mapping (Oracle `col AS (expr)` → PostgreSQL `col type GENERATED ALWAYS AS (expr) STORED`), the smarter move when the virtual column existed only to be indexed (use a PostgreSQL expression index and store nothing), the IMMUTABLE requirement that trips up expressions using dates or user functions, and the restrictions that bite silently — a generated column can't be a partition key, can't reference another generated column, and can't have a default.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL Table Inheritance vs Partitioning: When to Use Each
PostgreSQL has two features that look like the same thing and aren't: table inheritance and declarative partitioning. Inheritance is the older, general-purpose mechanism where child tables inherit a parent's columns — and it was how people faked partitioning before PostgreSQL 10, complete with the sharp edges (unique constraints and foreign keys aren't enforced across children, indexes don't cascade cleanly). Declarative partitioning (PARTITION BY RANGE / LIST / HASH) is the modern, purpose-built answer for large tables: real partitions, automatic partition pruning, and a clean syntax. For an Oracle DBA the mapping is simple — Oracle partitioned tables become PostgreSQL declarative partitions, not inheritance. This post explains the difference, why declarative partitioning is almost always the right call for time-series and archival-by-range workloads, the gotchas that bite (the partition key must be part of any primary/unique key, indexes are per-partition, pruning needs the key in your WHERE clause), and the rare cases where plain inheritance still earns its place.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Row-Level Security in PostgreSQL: Better Than Oracle VPD
Oracle's Virtual Private Database (VPD) enforces row-level access by attaching PL/SQL policy functions that return a predicate string, dynamically appended to every query. It works, but it's a body of procedural code to write, test and maintain out of band from the schema. PostgreSQL's Row-Level Security is the same idea done declaratively and in-core: you ENABLE ROW LEVEL SECURITY on a table and write CREATE POLICY … USING (predicate) — no policy function, no dynamic predicate assembly, the rule lives with the table. This guide maps VPD onto RLS: USING for what rows are visible vs WITH CHECK for what rows may be written, feeding tenant context through current_setting() instead of SYS_CONTEXT, permissive vs restrictive policies, and the one thing everyone trips on — table owners and superusers bypass RLS by default, so multi-tenant tables need FORCE ROW LEVEL SECURITY. The result is simpler, more transparent, and part of the schema you migrate rather than a separate codebase.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL8 min read
PostgreSQL Logical Replication: Architecture & Setup
Logical replication is the mechanism behind near-zero-downtime PostgreSQL migrations and upgrades, and it's worth understanding properly. Unlike physical (streaming) replication — which ships byte-exact WAL to a read-only standby of the entire cluster — logical replication streams row-level changes for the tables you choose, into a target that is itself writable and can even run a different major version. That combination is exactly what a cutover needs: replicate into the new database, let it catch up, then flip the application with seconds of downtime. This post covers the publication/subscription architecture, the setup (wal_level = logical, CREATE PUBLICATION, CREATE SUBSCRIPTION), and the limitations you must plan around: DDL is not replicated, sequences are not advanced on the subscriber (you sync them at cutover), and updates/deletes need a replica identity (a primary key). It also draws the line between when you want logical replication (migrations, upgrades, selective/consolidated feeds) and when physical replication is the right tool (a full hot-standby for HA).
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Full-Text Search in PostgreSQL: No Elasticsearch Needed
Reaching for Elasticsearch the moment you need search is a reflex worth questioning — for a large share of applications, PostgreSQL's built-in full-text search is enough, and it keeps your search data transactional and in one place. The model is tsvector (a document reduced to normalized lexemes) matched against tsquery with the @@ operator, accelerated by a GIN index, ranked with ts_rank, and excerpted with ts_headline. This guide shows the modern pattern — a STORED generated column holding to_tsvector('english', …) with a GIN index over it — plus websearch_to_tsquery for Google-style user input, and pg_trgm when you need fuzzy/typo tolerance. For Oracle DBAs it's the replacement for Oracle Text (CONTEXT indexes and CONTAINS). It also draws the honest line: where Postgres FTS is plenty, and where you genuinely have outgrown it (massive scale, advanced relevance tuning, faceting) and a dedicated search engine earns its keep.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
JSONB in PostgreSQL: When to Use It and When Not To
JSONB is one of PostgreSQL's best features and one of its most abused. It stores JSON in a binary, indexable form with a rich operator set (->, ->>, @>, jsonb_path_query) and GIN indexes for containment — genuinely powerful for variable or schemaless data. The trap is reaching for it too eagerly: dumping an entire relational schema into a single jsonb column throws away everything the database is good at — column types, constraints, foreign keys, and the planner statistics that make queries fast. This post draws the line. Use JSONB for the genuinely dynamic tail: sparse or variable attributes, external API payloads, user-defined fields. Keep the columns you actually filter, join and aggregate on as real, typed columns. It covers jsonb vs json (binary + indexable vs text), how to index it properly (GIN with jsonb_path_ops for @> containment, a B-tree expression index on col->>'field' for equality), and pulling hot fields out with a STORED generated column so the planner can use statistics on them.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
pg_stat_statements: Your New AWR
AWR and ASH are the first tools an Oracle DBA reaches for to find a slow database — and their absence is disorienting on PostgreSQL. The closest and most important replacement is pg_stat_statements: it aggregates normalized query statistics (calls, total and mean execution time, rows, shared-buffer hits vs reads) across the whole cluster, so 'which queries are actually costing me' is one ORDER BY away. This guide covers enabling it (shared_preload_libraries + CREATE EXTENSION + a restart — it can't be loaded on the fly), the handful of queries that find your real problems (top by total_exec_time, by mean, by I/O), how to reset the counters for a clean measurement window, and — honestly — where it falls short of AWR: it's cumulative since the last reset rather than snapshot-based, and it has no ASH-style wait sampling (that's a separate extension). Pair it with track_io_timing and auto_explain and it becomes the performance cockpit you install on day one.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL Extensions: The Hidden Superpower
Oracle ships as a monolith and sells capabilities as licensed options. PostgreSQL does the opposite: a lean core plus a rich ecosystem of extensions you add with a single CREATE EXTENSION — and most are free. For a migrating Oracle DBA this is the mental unlock, because a surprising number of Oracle features map directly onto an extension. DBMS_CRYPTO becomes pgcrypto; DBMS_SCHEDULER becomes pg_cron; database links become postgres_fdw; UTL_MATCH fuzzy matching becomes pg_trgm; and pg_stat_statements is your AWR. This post is a tour of the extensions that matter for migrations and operations — pg_stat_statements, postgres_fdw, pgcrypto, pg_trgm, citext, PostGIS, pgvector, pg_partman, pg_cron — how CREATE EXTENSION actually works, which ones need shared_preload_libraries and a restart, and the discipline of adding exactly what you need instead of paying for a bundle you mostly don't use.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL6 min read
Tablespaces in PostgreSQL: What Matters and What Doesn’t
This is the mapping that surprises Oracle DBAs most: you probably don't need your tablespaces. In Oracle a tablespace is fundamental — every segment lives in one, with quotas, storage parameters, and per-user defaults. In PostgreSQL a tablespace is far lighter: essentially a named symlink to a directory on another filesystem, and entirely optional. Everything lives happily in the default location (pg_default) with no tablespace at all. So the instinct to recreate an Oracle tablespace layout one-for-one is exactly wrong — it adds operational weight (base backups follow symlinks, replication must match paths) for no benefit. This post explains what PostgreSQL tablespaces actually do, the one real reason to create one (put specific hot tables or indexes on faster physical storage, e.g. NVMe), why they're cluster-wide rather than per-database, the role of temp_tablespaces for large sorts, and why collapsing a dozen Oracle tablespaces into the default is usually the right migration call.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
PostgreSQL Roles and Privileges: An Oracle DBA Translation
PostgreSQL has no separate concept of 'users' and 'roles' — there is one object, a ROLE, and a role that can log in IS a user. That single design choice reshapes everything an Oracle DBA knows about access control. This guide translates the model: CREATE USER is just CREATE ROLE … LOGIN; role membership replaces Oracle roles and GRANT role TO user; there are no profiles (password rules and connection limits live in pg_hba.conf and per-role CONNECTION LIMIT); and the biggest footgun of all — the PUBLIC pseudo-role and the default-open public schema, which grant more than most Oracle DBAs expect. It covers ownership vs privileges, why ALTER DEFAULT PRIVILEGES is the piece everyone forgets (new tables owned by a role aren't automatically visible to others), SET ROLE as your new SET CURRENT_SCHEMA-plus-identity, and how superuser differs from SYSDBA.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
pg_dump vs Oracle Export: A Backup Philosophy Shift
Reaching for pg_dump as if it were expdp is the fastest way to design a backup strategy that fails you at 3 a.m. They look similar — both take a logical, consistent snapshot of a database — but the philosophy differs. pg_dump is per-database and single-threaded by default (use -Fc or -Fd + -j for parallel, and pg_restore for selective, reorderable restores); globals like roles and tablespaces live outside it in pg_dumpall --globals-only. More importantly, logical dumps are NOT your production DR story: for point-in-time recovery you want a physical base backup (pg_basebackup) plus continuous WAL archiving — PostgreSQL's answer to RMAN + archived redo. This post maps exp/expdp and RMAN onto the PostgreSQL world, explains -Fc vs -Fd vs -Fp, when logical beats physical (migrations, single-table restores, version upgrades) and when it doesn't (fast recovery of a large database), and why pg_dump has no incremental mode — because incrementals are a physical/WAL concern.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL6 min read
psql vs SQL*Plus: Your New Command Line
SQL*Plus muscle memory doesn't transfer to psql, and the friction in the first week of a PostgreSQL migration is almost all command-line. This is the translation table Oracle DBAs actually need: DESCRIBE → \d (and \d+, \dt, \df, \dn); @script.sql → \i script.sql; SPOOL → \o; SET LINESIZE/PAGESIZE → \pset and the magic \x for expanded row-per-line output; DEFINE variables → \set and :'var'; SHOW/ALTER SESSION → SHOW and SET. It also covers what psql adds that SQL*Plus never had — \timing, tab-completion of table and column names, \e to edit the last query in your editor, \watch to re-run on an interval, and the fact that psql is autocommit-on by default (so BEGIN matters more than you're used to).
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL8 min read
PostgreSQL for Oracle DBAs: The Survival Guide
You know databases cold — the surprises in your first PostgreSQL month aren't about SQL, they're about a different set of assumptions. This survival guide covers the mental-model shifts that trip up experienced Oracle DBAs: every connection is its own OS process (so a realistic max_connections is in the low hundreds and a pooler like PgBouncer is not optional under load); MVCC keeps old row versions in the table itself, so VACUUM and autovacuum replace undo/rollback segments and bloat is a thing you monitor; there are no packages (schemas + functions), no query hints (you fix the planner's inputs instead), and no SGA to tune the Oracle way (shared_buffers + the OS page cache). Add the quiet ones that cause real bugs — unquoted identifiers fold to lowercase, not uppercase; a role is a user; search_path is your CURRENT_SCHEMA — and you have the map for week one.
Rakesh Mamidala
Founder & Lead Engineer
Migration6 min read
The Oracle Migration Questions We Hear Most (Answered)
After a run of deep technical posts, here's the plain-language round-up: the seven questions that come up in almost every Oracle→PostgreSQL conversation, each with a straight answer and a link to go deeper. How long will it really take, and what actually drives the timeline? Will my PL/SQL convert automatically (and what's the honest percentage)? What happens to XMLType, CLOBs and BLOBs? How do you PROVE no data was lost, rather than just hoping? Can we cut over with near-zero downtime? What breaks that teams don't see coming? And do we have to rewrite the application? This is the orientation piece for anyone weighing a migration — the questions distilled, the answers direct, and pointers into the detailed guides for each one.
Rakesh Mamidala
Founder & Lead Engineer
Migration7 min read
Migrating Oracle LOB and XML Columns to PostgreSQL
CLOB, BLOB, NCLOB and XMLType are where a lot of Oracle→PostgreSQL migrations quietly go wrong — first on correctness, then on speed. The mapping isn't always obvious: XMLType is NOT JSON (map it to PostgreSQL's native xml type, never jsonb, or every row fails with 'invalid input syntax for type json'), CLOB/NCLOB become text, BLOB becomes bytea, and BFILE has no real equivalent. Then there's the performance trap: LOB columns carry their full payload in every fetched row, so a big read batch × several LOBs per row blows up memory and stalls the load — a table that looks frozen but is technically still running. This post covers the correct type mappings for Oracle LOBs, why XMLType→jsonb is a silent footgun, how to read LOBs efficiently (fetch as str/bytes, not LOB locators), and why LOB-heavy tables need a smaller batch size than the rest of your schema.
Rakesh Mamidala
Founder & Lead Engineer
Migration6 min read
What Happens When a Migration Crashes Halfway?
A bulk migration dies at 70% — the network drops, the box reboots, someone hits Ctrl-C. The scary question is what the restart does. Naive tools either start over (wasting hours re-copying what already landed) or blindly resume and double-load a chunk that committed but wasn't recorded as done — silently duplicating rows on any table without a unique key. The fix is idempotency: make 'the data is committed' and 'this chunk is done' the same atomic fact, so a resume can safely skip exactly what finished and redo exactly what didn't. This post explains the commit-vs-checkpoint race that causes duplicate rows on resume, why a table with no primary key makes it invisible, and how a per-chunk done-marker written inside the same transaction as the COPY makes resume crash-safe — no duplicates, no loss.
Rakesh Mamidala
Founder & Lead Engineer
Migration5 min read
Plenty of Migration Tools Exist — Here's What Makes Ours Different
"There are already plenty of migration tools — what makes yours different?" It's the first question we get, and it deserves an honest answer. Most tools do one slice of the job: schema converters convert DDL, cloud DMS replicates data, CDC platforms stream changes. None of them tie schema + code + data + proof into one trustworthy flow, and almost none answer the question that actually matters the night before cutover: how do you KNOW every row arrived correctly? This post lays out the five things DBMigrateAIPro does differently — per-partition cryptographic validation with a saved proof artifact, schema and PL/SQL code conversion in one tool, a dependency-aware dry-run plan with a 95/5 gap report, a conversational copilot that runs assess→plan→migrate→verify, and a private, free, fully-unlocked edition — plus an honest word on where Ora2Pg and AWS DMS still fit.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Connection Pooling: PgBouncer vs Oracle Connection Manager
Connection pooling never shows up in a schema diff, but it's one of the most common reasons a freshly-migrated PostgreSQL falls over under load. Oracle quietly multiplexes connections (Shared Server, DRCP, Connection Manager); PostgreSQL gives every connection its own OS process, so a realistic max_connections is in the low hundreds. This guide maps Oracle's pooling to PostgreSQL (DRCP → PgBouncer transaction mode, CMAN → PgBouncer + HAProxy), explains PgBouncer's session/transaction/statement modes and what transaction mode breaks (server-side prepared statements, session SET/search_path, advisory locks, LISTEN/NOTIFY), and how to size it — many clients, few real connections.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Parallel Query in PostgreSQL vs Oracle: What You Gain
In Oracle you often ask for parallelism with a PARALLEL hint; in modern PostgreSQL it's automatic — the planner spins up workers for big scans, joins, and aggregates whenever the cost model says it pays. This guide covers what PostgreSQL parallelizes (parallel seq/index scans, joins, and aggregates), the knobs that control it (max_parallel_workers_per_gather, max_parallel_workers, min_parallel_table_scan_size), why a query might stay serial (small table, writes, parallel-unsafe functions), and parallel B-tree index builds — a real speedup for the post-data step of a migration.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Oracle Hints vs PostgreSQL: How to Influence the Planner
Oracle developers override the optimizer with hints — INDEX, LEADING, USE_NL, PARALLEL. The first surprise in PostgreSQL: there are no query hints, by deliberate design. PostgreSQL's philosophy is to fix the planner's inputs, not patch its output. This guide maps each Oracle hint to its PostgreSQL approach: better statistics (ANALYZE, SET STATISTICS, CREATE STATISTICS for column correlations), session-level enable_* flags for diagnosis only, and the pg_hint_plan extension as a genuine last resort.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL7 min read
Query Optimization After Migration: The First 30 Days
The data landed and validation passed — then a report that took 2 seconds on Oracle takes 40 on PostgreSQL. This is normal and fixable. PostgreSQL's planner is different and, right after a bulk load, flying blind. This guide is the first-30-days playbook: run ANALYZE on day one (the single highest-leverage action), find the real slow queries with pg_stat_statements, read plans with EXPLAIN (ANALYZE, BUFFERS), tune the cost inputs for SSD (random_page_cost, effective_cache_size, work_mem), and verify your migrated indexes are actually being used.
Rakesh Mamidala
Founder & Lead Engineer
Migration6 min read
Character Set Migration: Oracle to PostgreSQL UTF-8
Character-set migration is the one that passes every row count and then surfaces weeks later as a customer named José showing up as Jos?. The fix is mostly one good decision up front — target PostgreSQL in UTF-8 (it maps cleanly to Oracle AL32UTF8) — plus an honest audit of the BYTE-vs-CHAR trap (Oracle VARCHAR2(n BYTE) holds bytes; PostgreSQL VARCHAR(n) counts characters, so multibyte data can overflow), the US7ASCII landmine (8-bit data stuffed in a 7-bit charset), and why only value-level (Merkle) validation — not row counts — catches a botched transcode.
Rakesh Mamidala
Founder & Lead Engineer
Oracle7 min read
Migrating Oracle Materialized Views to PostgreSQL
An Oracle materialized view's DDL converts cleanly — the trap is keeping it current. Oracle has FAST incremental refresh (via MV logs), REFRESH ON COMMIT, and automatic query rewrite; PostgreSQL has exactly one primitive, REFRESH MATERIALIZED VIEW, which rebuilds the whole thing. This guide maps every Oracle refresh mode to a real PostgreSQL strategy: COMPLETE → scheduled refresh via pg_cron, ON COMMIT → an AFTER trigger, and the honest gap — FAST refresh has no native equivalent (scheduled full refresh, trigger-maintained summary tables, or pg_ivm). Plus the UNIQUE-index prerequisite for REFRESH … CONCURRENTLY and the silent query-rewrite optimization PostgreSQL never performs.
Rakesh Mamidala
Founder & Lead Engineer
Oracle7 min read
Oracle DATE vs PostgreSQL TIMESTAMP: Avoid the Traps
Oracle's DATE type carries a time component down to the second — PostgreSQL's DATE is date-only. Map one straight to the other and every hour, minute, and second is silently dropped while row counts still report success. This guide gives the correct mapping (DATE → TIMESTAMP, TIMESTAMP WITH TIME ZONE → TIMESTAMPTZ), the date-arithmetic trap where Oracle's `d + 1` becomes PostgreSQL's `d + INTERVAL '1 day'`, the SYSDATE / TRUNC / ADD_MONTHS / TO_DATE function swaps, the UTC time-zone model, and why only column-level validation catches a botched DATE mapping.
Rakesh Mamidala
Founder & Lead Engineer
Migration7 min read
Handling Oracle NULLs and Empty Strings in PostgreSQL
The nastiest silent difference in an Oracle→PostgreSQL migration: Oracle treats an empty string '' as NULL, while PostgreSQL treats '' as a real, distinct, non-null value. Row counts match, the migration reports success, and then code relying on IS NULL to catch empty Oracle strings quietly returns wrong answers. This guide shows the difference in action, how to decide the mapping per column (usually: coerce '' → NULL to preserve Oracle semantics), the concatenation and NOT NULL traps that follow, and why only column-level (Merkle) validation — not row counts — catches it.
Rakesh Mamidala
Founder & Lead Engineer
Oracle8 min read
Oracle DB Links vs PostgreSQL FDW: The Migration Path
Oracle database links let a query reach into another database as if its tables were local. PostgreSQL replaces them with Foreign Data Wrappers (FDW) — more explicit, more secure, and able to federate Postgres, Oracle, MySQL and more. This guide covers picking the wrapper (postgres_fdw / oracle_fdw / dblink), the four-step setup that replaces CREATE DATABASE LINK (extension → server → user mapping → foreign table / IMPORT FOREIGN SCHEMA), rewriting @dblink references, and the three things to get right: predicate push-down, credentials in the user mapping, and cross-server writes.
Rakesh Mamidala
Founder & Lead Engineer
Oracle7 min read
Migrating Oracle Synonyms: What PostgreSQL Offers Instead
Synonyms are one of the few Oracle features with no direct PostgreSQL equivalent — there is no CREATE SYNONYM. But once you map each synonym to its intent, almost all of them disappear: schema-qualification convenience becomes a search_path entry, a genuine rename becomes a view or a thin wrapper function, and PUBLIC synonyms become a shared schema on every role's path. This guide gives the intent-to-replacement map, the search_path mechanic that does most of the work, the PUBLIC-synonym pattern, resolution-order gotchas, and the one case that needs a real object.
Rakesh Mamidala
Founder & Lead Engineer
Oracle8 min read
Oracle Triggers in PostgreSQL: Full Migration Guide
Triggers are one of the friendliest parts of an Oracle→PostgreSQL migration — the concepts map almost one-to-one — but one structural difference trips up every first-timer: Oracle inlines the trigger body, while PostgreSQL splits it into a trigger function plus a binding. This guide walks the full translation map (:NEW/:OLD, TG_OP, WHEN, INSTEAD OF), a worked BEFORE-INSERT example, the RETURN NEW rule that silently drops rows when forgotten, firing order without FOLLOWS, the mutating-table pain that simply disappears in PostgreSQL, and the one hard case — autonomous-transaction audit triggers — that genuinely needs a human.
Rakesh Mamidala
Founder & Lead Engineer
Migration9 min read
What a Migration Assessment Report Should Include
A migration assessment report is the artifact that turns “we should move off Oracle” into a plan you can staff and schedule. A good one is specific, numeric, and honest about the hard 5%. Here are the ten sections every assessment report should contain — object inventory, data profile, PL/SQL surface, the hard-construct catalog, dependency map, a risk score, an effort estimate, and the recommended approach — plus the red flags of a useless one.
Rakesh Mamidala
Founder & Lead Engineer
AI10 min read
Migration Copilot: An AI That Runs on Your Machine, Not Someone Else’s Cloud
Most “AI migration assistants” ship your schema — sometimes your data — off to a third-party API. For a regulated database that’s a non-starter. So we built Migration Copilot to run locally: a conversational assistant that drives the migration engine through tools, asks before anything destructive, and needs no API key and no internet. Here’s the architecture, the safety model, and why local-first is the right default for database work.
Rakesh Mamidala
Founder & Lead Engineer
Migration10 min read
How to Estimate Migration Timeline: The Honest Formula
Most migration estimates are wrong in the same direction — they anchor on data size, which is rarely the bottleneck. The honest formula budgets five things: data movement, code conversion, the handful of hard constructs, validation, and application-layer changes. Here's the breakdown, a worked example, and the contingency multiplier nobody likes but everybody needs.
Rakesh Mamidala
Founder & Lead Engineer
Migration11 min read
The 10 Biggest Oracle Migration Mistakes (And How to Avoid Them)
After 500+ migrations, the mistakes that hurt are predictable — and most happen before anyone writes a line of conversion code. Row counts mistaken for validation. NULLs collapsed into empty strings. Sequences that aren't resynced at cutover. Here are the ten that show up most, why each one bites, and the one-line fix for each.
Rakesh Mamidala
Founder & Lead Engineer
Migration10 min read
Building a Migration Risk Matrix: Step by Step
An assessment hands you a list of findings. A risk matrix turns that list into priorities — what to fix first, what to watch, and what's safe to accept. Here's how to build one for an Oracle-to-PostgreSQL migration: the two axes that matter, the standard risk catalog, a scoring method that survives scrutiny, and how to keep it a living document instead of a one-time slide.
Rakesh Mamidala
Founder & Lead Engineer
Migration11 min read
How to Assess Your Oracle Database Before Migration
The highest-leverage hour of any Oracle-to-PostgreSQL migration is spent before you move a single row. A complete assessment — object inventory, data profile, PL/SQL surface area, the handful of genuinely hard constructs, and dependency map — turns cutover surprises into a planned punch list. Here's exactly what to measure, the SQL to measure it, and how to turn the findings into a risk score you can plan against.
Rakesh Mamidala
Founder & Lead Engineer
Migration12 min read
Data Type Mapping: Oracle to PostgreSQL Complete Reference
The reference table you wish your migration tool came with. Every Oracle type, the PostgreSQL equivalent, the precision / length / semantic gotchas, and which mappings are silent-data-loss risks vs which are clean. NUMBER variants, VARCHAR2 BYTE vs CHAR, the Oracle DATE-includes-time trap, LOBs, XMLTYPE, spatial, intervals, ROWID, and a few Oracle-only types with no PostgreSQL equivalent.
Rakesh Mamidala
Founder & Lead Engineer
Engineering10 min read
How DBMigrateAIPro Mathematically Proves Your Data is Correct
Most migration tools tell you 'X rows copied'. We tell you the same — and hand you a cryptographic proof that every column of every row landed exactly right. Per-partition Merkle roots, computed on both sides during COPY, compared in seconds. Verification cost goes from O(N) to O(log N). On a 1B-row table, that's hours → seconds. None of DMS, GoldenGate, Striim, or Fivetran ship this. Here's how it works.
Rakesh Mamidala
Founder & Lead Engineer
Migration11 min read
Oracle Packages in PostgreSQL: How We Solve the Biggest Challenge
Oracle packages are the single hardest construct to migrate to PostgreSQL — there's no direct equivalent. PG has schemas + functions, not packages. But the pattern that works in production is well-understood: one schema per package, package-state via session-local tables or set-returning functions, and PRAGMA AUTONOMOUS_TRANSACTION via dblink. A concrete walkthrough with real before/after code.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL8 min read
Oracle Sequences vs PostgreSQL: What Changes and Why
Sequences look identical between Oracle and PostgreSQL — until they aren't. Both have CREATE SEQUENCE, NEXTVAL, CACHE. But the way you call a sequence in a DEFAULT clause differs, IDENTITY columns are the modern replacement for the legacy sequence + trigger pattern, and the post-migration sequence resync is the single most common source of 'primary key already exists' errors at cutover. A practical guide with concrete before / after SQL.
Rakesh Mamidala
Founder & Lead Engineer
Migration10 min read
PL/SQL to PL/pgSQL: The Complete Conversion Guide (Part 1)
Most of PL/SQL maps cleanly to PL/pgSQL — block-structured, cursor-aware, exception-handling syntax all carry across with minor changes. Part 1 walks through the constructs every migration project handles: type mappings, variables, built-in functions, cursors, conditionals, loops, exceptions, and DBMS_OUTPUT. With before/after examples you can paste straight into a transpiler test.
Rakesh Mamidala
Founder & Lead Engineer
PostgreSQL8 min read
5 Signs Your Team is Ready for PostgreSQL
Most teams know whether PostgreSQL is the right next move — but they ask the question too late, after a roadmap commitment or project deadline forces it. Five observable signals from 500+ migrations that your team is ready, plus a readiness scorecard. If 3 match, you should be scoping this quarter.
Rakesh Mamidala
Founder & Lead Engineer
Migration10 min read
What Makes a Database Migration Succeed (Or Fail)
70-80% of database migrations are said to fail or over-run. After 500+ migrations, the patterns are predictable — and they're not what most teams expect. Five failure modes, five success predictors, and where the time actually goes.
Rakesh Mamidala
Founder & Lead Engineer
Engineering11 min read
PostgreSQL vs Oracle: A DBA's Honest Comparison After 20 Years
No marketing pitch — a working DBA's side-by-side look at Oracle and PostgreSQL across performance, cost, tooling, HA, and where each one genuinely wins in 2026.
Rakesh Mamidala
Founder & Lead Engineer
Engineering6 min read
Why We Built DBMigrateAIPro: The Migration Tool We Always Needed
After 20 years and 500+ enterprise database migrations, we got tired of the tools that existed. So we built our own — with AI-powered PL/SQL conversion, zero-downtime CDC cutover, and row-hash validation.
Rakesh Mamidala
Founder & Lead Engineer
Guide18 min read
Oracle to PostgreSQL Migration: A Complete Step-by-Step Guide
Everything you need to migrate from Oracle to PostgreSQL — schema conversion, PL/SQL transpilation, data migration, CDC cutover, and post-migration validation.
Rakesh Mamidala
Founder & Lead Engineer
Engineering14 min read
PL/SQL to PL/pgSQL: What Changes and What Stays the Same
A hands-on guide covering every PL/SQL construct that needs manual or automatic conversion to PL/pgSQL — packages, sequences, cursors, exceptions, and more.
Rakesh Mamidala
Founder & Lead Engineer
Engineering12 min read
Zero-Downtime Database Migrations Using CDC
How Change Data Capture (CDC) enables near-zero-downtime cutover: run Oracle and PostgreSQL in sync for weeks, then flip the switch with seconds of downtime.
Rakesh Mamidala
Founder & Lead Engineer
Best Practices10 min read
The 40-Point Oracle Migration Checklist (Before You Start)
Skip the painful surprises. This pre-migration checklist covers supplemental logging, XMLTYPE, partitioned tables, sequences, circular FKs, and 34 more gotchas.
Rakesh Mamidala
Founder & Lead Engineer
Architecture8 min read
ETL vs ELT in 2026: Which Should You Choose?
The rise of cloud data warehouses changed the ETL vs ELT debate. We break down when each approach makes sense and how to pick the right pattern for your stack.
Rakesh Mamidala
Founder & Lead Engineer
Best Practices10 min read
Why Data Validation Is the Most Underrated Migration Step
Most migration failures aren't schema problems — they're data quality problems discovered too late. Here's how to build a validation layer that catches issues before production.
Rakesh Mamidala
Founder & Lead Engineer