Introduction
Every AEM instance needs to behave differently depending on where and how it's running — an author instance shouldn't expose the same things a publish instance does, a dev environment shouldn't use production credentials, and a US-region instance might need different configuration than an EU-region instance. AEM solves this with Run Modes: labels attached to an instance at startup that determine which OSGi configurations, content, and behaviors get activated. Understanding run modes is foundational — nearly every real AEM project uses them to manage environment-specific configuration (database URLs, API keys, replication agents, cache settings) without maintaining separate codebases. After reading this article, you'll understand the built-in run modes AEM ships with, how to define your own custom run modes, the critical rule of mutual exclusion that governs install-time run modes, and how run modes map to the ports you learned about when installing AEM locally. Prerequisites: Familiarity with installing AEM locally (see Installing AEM Server Locally.md) and basic OSGi/config folder structure concepts.
What Is a Run Mode?
A run mode is simply a string label assigned to a running AEM instance. When AEM starts, it checks which run modes are active and uses that information to decide:
Which OSGi configurations to apply (via
config.<runmode>folders)Which content packages to install
Which bundles to start or skip
How certain core features behave (e.g., whether the Replication/Package install UI is restricted)
Run modes are evaluated against your repository's /apps and /libs structure through a naming convention: any folder suffixed with .<runmode> only applies when that run mode is active.
That last example is important — multiple run modes can be combined, and a folder with multiple dot-separated run modes requires all of them to be active simultaneously for its configs to apply.
How Run Modes Are Set
Run modes are specified at JVM startup using the -r flag (as you saw in the local installation article):
This instance now has three run modes active simultaneously: author, dev, and local. AEM merges configurations from config/, config.author/, config.dev/, config.local/, and any combined folders like config.author.dev/ — all at once.
You can also append run modes after the instance has already been created by editing the crx-quickstart/bin/start script, or by checking/setting them via the Web Console at /system/console/vmstat or /system/console/configMgr (though the cleanest approach is always to set them at startup).
Pre-Built (Out-of-the-Box) Run Modes
AEM ships with a set of run modes that are either automatically assigned or part of its standard vocabulary. These fall into a few categories.
1. Installation-Time Run Modes: author and publish
These are the two most fundamental run modes in all of AEM, and they're mutually exclusive (more on that below). You choose one at install time:
author— Marks the instance as a content-authoring environment. Enables the authoring UI, CRXDE Lite, component dialogs, workflow consoles, and replication agents that push content out to publish instancespublish— Marks the instance as a content-delivery environment. Strips out authoring tooling by default, optimizes for read performance, and is the target that end-users/visitors actually hit (usually behind a Dispatcher)
2. Default Port-Associated Behavior
While ports themselves aren't run modes, there's a long-standing convention tightly linking run mode to port number:
Run Mode | Default Port | Purpose |
|---|---|---|
| 4502 | Authoring environment |
| 4503 | Delivery environment |
Additional | 4512, 4522... | Scaled authoring tier |
Additional | 4513, 4523... | Scaled delivery tier (load-balanced) |
The port is set independently via the -p flag — AEM doesn't force a port based on run mode — but every real-world project follows this convention so anyone on the team can immediately tell what an instance is just from its port number.
3. Environment/Topology Run Modes (Industry Convention, Not Enforced by Code)
AEM doesn't ship these as hardcoded values, but Adobe's own documentation and virtually every enterprise project uses this standard set for environment separation:
dev— Developer's local or shared dev environmentstage(orstaging/uat) — Pre-production, used for QA/UATprod— Production/live environment
These are passed alongside author/publish:
4. Automatically Assigned Run Modes
Beyond what you pass with -r, AEM automatically computes and adds certain run modes at startup that you don't control directly:
samplecontent— Active if sample content (like the We.Retail or WKND demo site) was installed. Absence of this run mode on a "nosamplecontent" quickstart avoids installing demo content at allCluster-related modes — When TarMK clustering or certain Oak configurations are in play, additional internal modes may be present
nosamplecontent— Some quickstart jar variants are literally named/configured to skip sample content installation entirely, which is standard for anything beyond a pure learning sandbox
5. Adobe-Reserved Namespaces
Adobe reserves a few run mode "families" for its own internal use that you should never try to repurpose for custom meanings:
Run modes starting with internal product prefixes used by AEM Forms, Communities, Screens, or Assets add-ons when those are installed (e.g., specific modes activated automatically when the Forms add-on package is present)
Custom Run Modes
Beyond the built-in vocabulary, you can — and in real projects, must — define your own run modes to represent anything specific to your business or infrastructure.
Common Custom Run Mode Examples
This enables configuration folders like:
Both configs target the exact same OSGi service (PaymentGatewayConfig), but only one activates depending on which combined run mode set is active on that particular instance — no code branching required.
Defining Custom Run Modes at Startup
Custom run modes are passed exactly like built-in ones via -r, comma-separated, no special registration needed:
Defining Custom Run Modes Dynamically (Install-Time vs. Runtime)
There are actually two categories of run modes in AEM, and this distinction matters a lot:
1. Install-Time Run Modes (also called "fixed" run modes)
Set once via
-rat the very first startup (or viasling.run.modesinsling.properties)Written into
crx-quickstart/launchpad/sling.propertiesas thesling.run.modes.installpropertyCannot be changed after the instance is first provisioned without wiping/reinstalling — this is intentional, since things like
author/publishfundamentally shape the repository structure and shouldn't change mid-life
2. Runtime-Changeable Run Modes
Some run modes (particularly custom ones you add later, or ones not in the original fixed set) can be appended dynamically by editing
sling.propertiesdirectly, or occasionally through JVM system properties on restart, without a full reinstallLess common in practice — most teams decide all their run modes up front and bake them into each environment's startup script
For nearly all practical purposes: decide your full run mode list before first startup, especially author vs. publish, since changing it later is disruptive.
Where Custom Run Mode Values Live
The actual active run mode set for a running instance is stored in:
You can verify active run modes on a running instance via the Web Console:
Look for the "Active Sling Settings" section, which lists the exact run mode set currently in effect.
Mutual Exclusion: The Critical Rule
This is the single most important constraint to understand about run modes, and it trips up nearly every AEM beginner at least once.
The Rule
author and publish are mutually exclusive. An AEM instance must be started with exactly one of them — never both, never neither (in practice, you always need one or the other for a functioning instance).
Why This Matters
Author and publish run modes drive fundamentally incompatible configurations:
Behavior | Author Config | Publish Config |
|---|---|---|
CRXDE Lite access | Enabled | Disabled |
Component authoring dialogs | Active | Not needed (read-only rendering) |
Replication agents | "Publish" agents configured (push content OUT) | "Reverse replication" / flush agents configured (push activity logs back) |
User-facing authentication | Author-only users | Public/anonymous access patterns |
Workflow launchers | Full workflow console active | Typically disabled or minimal |
Default ACLs (access control) | Author group permissions | Anonymous/public read permissions |
If both run modes were active simultaneously, AEM would try to apply both sets of OSGi configurations at once, producing conflicting replication agent setups, broken security postures (e.g., accidentally exposing author-only functionality publicly), and generally undefined behavior. AEM doesn't gracefully "merge" these — it's an architectural assumption baked throughout the product that an instance is one or the other.
Mutual Exclusion Beyond Author/Publish
While author/publish is the textbook example, the same principle of "pick one, not both" commonly applies to any run modes representing mutually incompatible deployment contexts you define yourself — for example:
AEM itself won't stop you from doing this (unlike author+publish, which causes clear structural problems) — but it will silently merge configuration from both config.publish.prod.us/ and config.publish.prod.eu/, which is almost certainly not what you want. This is why good run mode design treats certain custom run mode groups (region, brand, tenant) as logically mutually exclusive even though AEM doesn't technically enforce it at the framework level the way it does with author/publish.
Combinable (Non-Exclusive) Run Modes
In contrast, most other run modes are designed to be combined freely:
dev, stage, prod (environment tier) typically combine cleanly with author/publish (instance type) and with custom modes like region or brand — that's the entire point of the system: layering independent, combinable dimensions of configuration (instance type × environment × region × brand) without writing conditional code.
Run Modes and Ports: How They Relate
Run modes and ports are independent settings — one does not cause the other — but in practice they're always used together to build a coherent multi-instance local or clustered setup. Revisiting the installation conventions:
Why Pairing Matters in Practice
Local development: You typically run one author (4502) and one publish (4503) instance side-by-side to test the full author → activate → publish flow
Clustering: When scaling publish horizontally, each additional publish instance gets both the
publishrun mode and a new port:Bash / CLIAll three share the
publishrun mode (and therefore identical OSGi config), but run on different ports and are typically load-balanced behind a Dispatcher/reverse proxyMulti-region or multi-brand farms: Combine run mode layering with port separation so each instance is both logically configured correctly (via run mode) and network-addressable distinctly (via port):
Bash / CLI
Port Does NOT Determine Run Mode
A common beginner misconception: thinking that running on port 4502 makes an instance an author instance. It does not. Port is purely a network binding; run mode is purely a configuration/behavior switch. You could, in theory, run a publish-run-mode instance on port 4502 — it would work, it would just break every convention your team relies on to quickly identify instances. Always set both explicitly and keep them aligned with convention.
Practical Example: Multi-Environment Configuration with Run Modes
Imagine a project with this OSGi config structure for a database connection service:
When you deploy the exact same code package to four different instances started with different run modes, each one automatically picks up the right database connection — no manual reconfiguration, no environment-specific code branches, no risk of a developer accidentally pointing a dev instance at production data because the correct config is baked into the run mode structure itself.
Common Pitfalls
Pitfall 1: Setting Both author and publish
The Mistake: Copy-pasting a startup script and forgetting to remove one run mode, ending up with -r author,publish.
Why It Happens: Usually a leftover from testing or a careless script template.
Fix: Always explicitly audit your startup scripts per environment; consider a sanity-check step in deployment automation that fails the build if both appear together.
Pitfall 2: Assuming Run Mode Changes Take Effect on a Running Instance
The Mistake: Editing sling.properties while AEM is running and expecting configs to reload immediately.
Why It Happens: Run modes (especially author/publish) are evaluated largely at startup; some config changes won't fully apply without a restart.
Fix: Always restart the instance after changing run modes.
Pitfall 3: Overlapping Custom Run Modes Without Realizing It
The Mistake: Defining both config.publish.us/ and config.publish.eu/ folders, then accidentally starting an instance with -r publish,prod,us,eu (perhaps copy-pasted from a multi-region deployment script).
Why It Happens: AEM doesn't block this combination the way it blocks author+publish, so there's no hard error — configs silently merge/conflict.
Fix: Treat logically exclusive custom run mode groups (region, brand, tenant) with the same discipline as author/publish, even though AEM won't enforce it for you. Document which run mode groups are mutually exclusive in your project's README.
Pitfall 4: Confusing Port Number with Run Mode
The Mistake: Assuming an instance running on 4503 is automatically in publish mode.
Fix: Always explicitly verify active run modes via /system/console/vmstat, not by inferring from the port.
Pitfall 5: Trying to Change author/publish After the Fact
The Mistake: Attempting to convert an existing author instance into a publish instance by just changing the -r flag on restart.
Why It Happens: Misunderstanding that these are "install-time" run modes baked deeply into the initial repository setup and default configuration.
Fix: If you genuinely need a different instance type, provision a fresh instance rather than attempting to flip an existing one.
Key Takeaways
What Run Modes Are
String labels assigned at JVM startup (
-r run mode1,runmode2,...) that determine which OSGi configurations and content get appliedConfiguration folders use dot-suffix naming (
config.author/,config.author.dev/) — multiple dots mean all those run modes must be active together
Pre-Built Run Modes
authorandpublish— the foundational, install-time, mutually exclusive instance-type run modesdev,stage,prod— industry-standard environment tier run modes (convention, not hardcoded by AEM)samplecontent/nosamplecontent— control demo content installationAdobe reserves certain run mode namespaces for add-on products (Forms, Communities, Screens)
Custom Run Modes
Freely definable for region, brand, tenant, or any project-specific dimension
Passed the same way as built-in ones via
-rInstall-time run modes are fixed once set (stored in
sling.properties) and shouldn't be changed without reprovisioningCombine cleanly with instance-type and environment run modes for layered configuration
Mutual Exclusion
authorandpublishmust never both be active — AEM's architecture assumes an instance is exactly one or the other; combining them produces conflicting replication, security, and authoring configurationsCustom run mode groups representing incompatible contexts (e.g., region or brand) should be treated as mutually exclusive by convention, even though AEM doesn't technically block combining them
Ports
Run mode and port are independent settings — port never determines run mode
Convention: 4502 for author, 4503 for publish, with incrementing ports (4512, 4513, 4522, 4523...) for additional clustered or multi-region instances
Always pair run mode and port explicitly and consistently in startup scripts to avoid team confusion