Thinking about an upgrade from CQ to AEM and wondering what will break first? You are not alone. Teams still on CQ5 are staring at AEM 6 and the shiny new Touch UI, Oak, and a different way to think about content and code. The press releases make it sound like a walk, but the details matter and they live in your repository, your dispatcher config, your clientlibs, and the expectations of the folks who author content every day. The difference between a smooth cutover and a month of whack a mole is a plan that respects what CQ let you get away with and what AEM will not forgive.
The short version is this: know your traps, write them down, and prove each fix in a lower environment.
Let us start with the biggest shift. CRX2 to Oak. Many teams still treat their repository like a bottomless drawer. In CQ that sometimes worked. In AEM with TarMK or MongoMK the rules are different. Old queries that leaned on magic indexing or casual XPath can go slow, or go sideways. If your project relies on big unbounded queries for navigation or search facets, you will feel it. Package size is another silent killer. One fat package with everything will look fine on a dev box and stall in a shared test environment. Also watch version storage bloat. Years of page activations can add gigabytes that now move slower and index differently. Your first pitfall is not code, it is the shape and size of your content and the way your queries behave in Oak.
Fix it with a content audit, explicit Oak indexes, and smaller deployment packages.
Next up is the author experience. Touch UI versus Classic UI is not a coat of paint. Dialogs that rely on Classic only widgets, custom sidekicks, or old clientlibs will frustrate authors the day after go live. The Touch UI shell changes paths and expectations, and your project code may assume Classic paths for things like design dialogs or in place editing. You can run Classic for a while, but if your roadmap includes Touch you must test every component in it and decide what gets refactored now. Sightly is here with cleaner templates, but moving everything at once is risk. Treat it like a new component set, not a search and replace.
Give authors a sandbox and real tasks before you switch the default UI.
On the back end, watch your OSGi bundles and their order. AEM ships with new versions of core APIs and some packages you pulled in are now outdated. That cute utility you grabbed from a blog post in the CQ5 era can drag in old dependencies and keep a platform bundle from resolving. Keep your run modes clean, avoid duplicate configs, and make sure your Sling mappings and resource types do not mask each other. If you built on private or internal APIs, replace them. The Felix console will tell you what is unresolved, but be ready to chase one missing import through a chain of bundles until you find the one jar that does not belong.
Strive for fewer bundles with clear ownership and upgrade third party jars first.
Your dispatcher is another upgrade gate. AEM changes URLs in Touch and shifts some clientlib paths. If your farm files are strict, you may block required libraries and watch authoring break in weird ways. Cache invalidation must be fast and predictable, or authors will see ghosts of old content on publish. Re check filters that allow POST to replication agents, flush agents, and health checks. Vanity URLs, SSL offload, and headers for caching need another pass. If you are moving from CQ rules collected over years, you will discover a few deny rules that made sense once and now block a core endpoint.
Test the dispatcher with a full author flow, not just home page hits.
Migration strategy is a choice between in place upgrade and fresh install with content load. In place can look faster but inherits every oddity. Fresh install forces discipline. Break your content into logical packages, drop versions older than your compliance window, and script user and group migration so ACLs come across clean. If you use replication agents with custom scripts, recreate them by hand and test on a clean publish. Watch workflows that listen on paths since Oak observes events a little differently and race conditions show up where you never saw them. Do not forget tags, design nodes, and any binaries that live outside DAM.
Plan a content freeze that is real and short, then dry run the whole thing.
People make or break this project. Train authors on Touch with your own components, not just the Geometrixx demo. Set expectations that some tasks remain in Classic during the first release. Give product owners a UAT checklist that matches how they actually work. Make a defect scale where styling nits do not block a launch but broken author workflows do. Communicate what changes in daily life like where to find siteadmin or how to switch between UIs. Your tech plan is only as good as your change plan.
Leadership support buys you the time to fix the right things first.
Here is a simple playbook that works. Discovery week to inventory content size, queries, custom bundles, and dispatcher rules. Branch the code for an AEM line and freeze features on CQ. Add Oak indexes and remove expensive queries. Normalize clientlibs and remove duplicate versions. Keep a Classic path for any component that is not ready for Touch and label it clearly. Stand up parallel environments for author and publish and run JMeter tests that exercise authoring, activation, and public traffic. Watch the logs for slow queries and reindex early. Rotate logs and set health checks so ops can see red lights before authors do. Finally run a full dress rehearsal with a real content package and a timed cutover so you know the script and the clock.
Make upgrades boring by shrinking the list of surprises.
Slow is smooth and smooth ships.