---
title: "October CMS vs Plone (2026): Architecture, TCO & Migration Guide"
slug: october-cms-vs-plone-2026-architecture-tco-migration-guide
date: 2026-08-18
author: Wahab
categories: [Migration Guide, General]
excerpt: "A technical comparison of October CMS (PHP/Laravel) and Plone (Python/Zope) covering architecture, TCO, security, and step-by-step migration paths between both platforms."
tldr: "October CMS fits Laravel-first teams building custom sites fast. Plone wins on security, workflows, and enterprise governance — but costs 2–3x more to operate and requires specialized Python/Zope talent."
canonical: https://clonepartner.com/blog/october-cms-vs-plone-2026-architecture-tco-migration-guide/
---

# October CMS vs Plone (2026): Architecture, TCO & Migration Guide


# October CMS vs Plone (2026): Architecture, TCO & Migration Guide

**October CMS is a PHP/Laravel CMS framework designed for developer-friendly website building with a relational database backend. Plone is a Python/Zope enterprise CMS with an object-oriented database (ZODB), built-in workflows, and a security track record trusted by government agencies worldwide.** These platforms share almost no architectural DNA. If you are comparing them, you are evaluating a move between PHP and Python ecosystems, weighing total cost of ownership, or planning a content migration between fundamentally incompatible data stores.

This is not a generic CMS comparison. Much like comparing [Sitefinity and ExpressionEngine](https://clonepartner.com/blog/blog/sitefinity-vs-expressionengine-architecture-tco-migration/), choosing between October CMS and Plone determines your hosting infrastructure, your hiring requirements, and your vendor lock-in exposure. Moving from one to the other is a full re-platforming effort that requires custom data engineering.

This guide breaks down the real architectural differences, TCO math, data model constraints, security posture, and migration paths between October CMS and Plone — with the technical specifics that matter for an actual decision.

## What Is October CMS?

<cite index="67-1">October CMS is a self-hosted content management system based on the PHP programming language and the Laravel web application framework.</cite> <cite index="67-2">It supports MariaDB, MySQL, PostgreSQL, SQLite, and SQL Server for the database backend and uses a flat file database for the frontend structure.</cite>

The current major version is **October CMS v4**, which shipped with significant improvements. <cite index="74-1,74-6">October CMS is now powered by Laravel 12</cite>, and <cite index="74-8">this version raises the minimum PHP requirement to 8.2.</cite> <cite index="71-1,71-2">Version 4.2 introduced a modernized frontend architecture — the administration panel was upgraded to Vue 3 and the JavaScript layer was migrated to native ES Modules (ESM), eliminating the need for build tools like Webpack or Laravel Mix.</cite>

<cite index="1-9">October CMS has garnered a reputation for its developer-centric approach, receiving praise for its clean interface and ease of customization, particularly from developers familiar with the Laravel framework upon which it is built.</cite> <cite index="1-12">However, October CMS offers a smaller selection of themes and plugins compared to its more established counterparts.</cite>

<cite index="74-13,74-14">With the 4.0 release, October CMS is now publicly available on GitHub. After five years of keeping the source code private, they're making it open again to improve accessibility and encourage community collaboration.</cite> Production use still requires licensing for update-gateway and Marketplace access.

## What Is Plone?

<cite index="7-4">Plone is a Python CMS with an object-oriented database based on Zope with a React frontend.</cite> <cite index="65-2">Plone is positioned as an enterprise CMS and is commonly used for intranets and as part of the web presence of large organizations.</cite>

The architecture stack runs deep: <cite index="7-6">Volto sits atop the REST API, which sits atop Plone, which sits atop Zope, which sits atop ZODB, which sits atop Python.</cite> <cite index="7-16,7-17">Volto is the default frontend for Plone 6, written in ReactJS. It uses the REST API to communicate with the backend and offers a modern editing experience.</cite>

<cite index="65-3">High-profile public sector users include the U.S. Federal Bureau of Investigation, Brazilian Government, United Nations, City of Bern (Switzerland), New South Wales Government (Australia), and European Environment Agency.</cite>

Plone is 100% free open-source software under the GPL, governed by the Plone Foundation. There are no license fees, no per-seat charges, no premium tiers.

## Architecture Comparison: October CMS vs Plone

This is where the decision gets real. These platforms solve different problems with entirely different technology stacks.

| Dimension | October CMS | Plone |
|---|---|---|
| **Language** | PHP 8.2+ | Python 3.10–3.14 |
| **Framework** | Laravel 12 | Zope + Zope Component Architecture |
| **Database** | Relational (MySQL, PostgreSQL, SQLite, SQL Server, MariaDB) | ZODB (object-oriented) or RelStorage (RDBMS adapter) |
| **Frontend** | Twig templates + Vue 3 admin | Volto (React) or Classic UI |
| **API** | Custom API via CMS pages or PHP routes, Artisan CLI | plone.restapi (full REST/hypermedia API) |
| **Templating** | Twig (server-side) | TAL/Zope Page Templates (Classic UI), React components (Volto) |
| **Extension model** | Plugin marketplace (Composer packages) | Python eggs/packages (PyPI, buildout or pip) |
| **Content modeling** | Relational tables per plugin + Tailor (YAML-defined content types) | Through-the-web or code-defined Dexterity content types stored as objects in ZODB |
| **Hosting** | Any PHP host, Docker | Self-hosted Linux, macOS, Windows, BSD, or Docker; minimum 2 GB RAM for Volto alone |
| **CI/CD tooling** | Artisan CLI, Composer, Git-tracked flat files | pip (modern), legacy buildout, plone.recipe.zope2instance |

### October CMS Data Model

October CMS sits directly on top of the Laravel framework, inheriting its service containers, Eloquent ORM, and Artisan command-line tools. Data is stored in standard relational tables. Each plugin defines its own schema via Laravel-style migrations.

<cite index="43-5,43-6,43-7">Migrations tell a story about your database history and this story can be played both forwards and backwards. A migration file defines a class that extends the `October\Rain\Database\Updates\Migration` class and contains two methods: `up` and `down`. The `up` method adds new tables, columns, or indexes, while the `down` method reverses those operations.</cite>

October also uses a hybrid data architecture for presentation:
- **Content and schema** are stored in the relational database via Eloquent ORM.
- **Presentation layers** (layouts, pages, partials) are stored as flat files in the file system using the Twig templating engine.

This flat-file approach means frontend developers can build entire themes using standard version control (Git) without touching the database. Tailor blueprints let you define content types in YAML, which generate admin UI and database tables automatically. The data stays in well-structured SQL tables you can query, export, or transform with standard database tooling — a significant advantage when it is time to migrate.

**CI/CD in October CMS:** Artisan CLI handles migrations, seeding, and cache operations. Flat-file templates commit to Git naturally. Composer manages PHP dependencies. This aligns with standard PHP deployment pipelines (GitHub Actions, Envoyer, Forge) without platform-specific configuration.

### Plone Data Model

<cite index="7-8">Data is stored in an object-oriented database called ZODB: Zope Object Database.</cite> This is the single biggest architectural differentiator. ZODB stores Python objects as serialized pickles in a binary format. There are no SQL tables, no rows, no columns. You cannot run `SELECT * FROM pages` against a Plone installation.

Plone uses **Dexterity** for content modeling. Dexterity types are defined via Python schemas or through the web interface. Everything in Plone is an object. The platform uses Zope's acquisition model, allowing objects to inherit properties and permissions from their parent containers.

<cite index="62-10,62-11">Plone uses the Zope Object Database for persistent storage and is therefore immune to SQL injection vulnerabilities. The database uses a binary format that cannot have user data inserted.</cite>

The security upside is real, but the migration cost is equally real. Data extraction requires either the REST API, ZODB introspection tools, or purpose-built export packages — not standard database tooling.

**RelStorage: when and why.** While Plone natively uses ZODB with a local `Data.fs` file, enterprise deployments often use **RelStorage** — an adapter that stores ZODB object pickles in PostgreSQL, MySQL, or Oracle. Choose RelStorage when you need: horizontal scaling across multiple Zope clients without ZEO, standard RDBMS backup tooling (pg_dump), or database-level replication. The critical caveat: RelStorage does not make Plone's data queryable via SQL. The rows it writes contain serialized pickle blobs, not human-readable columns. You still access all data through the ZODB API. The operational benefit is backup and clustering simplicity, not data portability.

**CI/CD in Plone:** Modern Plone deployments use pip with `constraints.txt` pinning and Docker-based deployment. The legacy buildout tool (`plone.recipe.zope2instance`) is still common in older installations. Two deployment surfaces (Volto Node.js process + Python/Zope backend) require coordinated release pipelines — a meaningful ops overhead compared to a single PHP application.

> [!WARNING]
> ZODB and relational databases are fundamentally incompatible storage paradigms. Migrating between October CMS and Plone is not a schema mapping exercise — it is a data transformation project that requires serializing objects on one side and deserializing into a completely different structure on the other.

## Security Comparison

Security posture is often the deciding factor for organizations evaluating Plone.

**Plone** has an exceptional security record. <cite index="37-9">The Plone Foundation states they have never received a report of a serious vulnerability in Plone being exploited in the wild.</cite> <cite index="37-3">Plone consistently has fewer vulnerabilities reported on databases than other content management systems.</cite> <cite index="62-14,62-15,62-16">Permission checks are done for every view or method accessed by incoming HTTP request. By contrast, other frameworks require the developer to implement access restrictions in the view on their own.</cite>

Plone is not vulnerability-free, though. <cite index="30-1">A 2024 CVE documented incorrect access control in Plone v6.0.9 allowing remote attackers to view and list all files via a crafted request.</cite> <cite index="35-6,35-7">In plone.rest, when the `++api++` traverser is used multiple times in a URL, handling it takes increasingly longer, making the server less responsive (CVE-2023-42457).</cite>

**October CMS** follows standard Laravel security practices — CSRF protection, encryption, PDO parameter binding, and authentication out of the box. But it inherits the broader PHP attack surface. <cite index="67-7">Ukrainian cybersecurity agencies identified that a 2022 attack on government websites involved exploitation of CVE-2021-32648, a vulnerability in October CMS.</cite>

The key difference: Plone's security is **architectural** — ZODB eliminates entire vulnerability classes like SQL injection at the storage layer. October CMS's security is **implementation-dependent** — a relational database plus PHP requires disciplined configuration, patching cadence, and developer discipline to maintain equivalent posture.

## Workflow, Permissions, and Multilingual Content

October CMS is better here than many PHP CMS comparisons suggest. Its multisite system can match by hostname and route prefix, switch themes by site, apply locale and timezone per site, and restrict site visibility by admin role. For multilingual or multi-brand estates run by a PHP team, that is a solid base.

Plone goes much further into **governed publishing**. Its permission model is a core design principle, not an afterthought:

- **Role-Based Access Control (RBAC):** Granular permissions that can be inherited or blocked at any level of the folder hierarchy, with per-object ACLs.
- **Advanced Workflow Engine:** Content can pass through complex, multi-state publication workflows (e.g., Draft → Pending Review → Legal Approval → Published) with different user roles assigned to each transition. <cite index="59-3">Plone doesn't tack on roles and permissions as an afterthought — they're core to how it works.</cite>
- **Multilingual content at scale.** <cite index="7-1">Plone adds to a Zope application: workflows, a framework to define content types, the feature to maintain multi-language content, a catalog indexing content, and many more features.</cite>
- **WCAG accessibility.** <cite index="59-6">Plone has historically prioritized web accessibility standards (like WCAG).</cite>

`plone.restapi` exposes users, groups, workflow, content rules, and type administration as formal API endpoints. If your destination state includes review states, group-based approval, document-heavy search, or institutional permissions, Plone starts with more first-party building blocks than October CMS can match without custom plugin development.

## Performance and Hosting Infrastructure Requirements

Both platforms require caching strategies to perform at scale, but their infrastructure demands differ substantially.

**October CMS** leverages Laravel's built-in caching drivers (Memcached, Redis) and file-based caching. Because templates are flat files, page rendering is fast. For high-traffic sites, standard LAMP/LEMP stack optimizations (Nginx + PHP-FPM + Redis) are sufficient. A minimum viable production deployment runs comfortably on a 1 GB RAM VPS (e.g., DigitalOcean Droplet at $6–12/month, AWS t3.micro). Shared PHP hosting works for low-traffic sites. From an ops perspective, October is usually the easier fit for a PHP shop — a single application deployment with standard tooling.

**Plone** is resource-intensive by comparison. The Plone documentation states that the Volto frontend requires **at least 2 GB RAM** on its own. A production-grade Plone stack typically requires:

- **Zope/ZODB backend:** 1–2 Zope instances, each consuming 256–512 MB RAM under normal load
- **Volto (Node.js SSR):** 2 GB RAM minimum, more under concurrent load
- **ZEO server** (if clustering multiple Zope instances): adds one additional process
- **Varnish** (effectively mandatory in production for HTTP caching): 256–512 MB RAM
- **HAProxy or Nginx** for load balancing across Zope clients

A realistic minimum viable Plone 6 production server is a **4 GB RAM instance** (e.g., DigitalOcean Droplet at $24/month, AWS t3.medium at ~$30/month). A clustered production environment (2 Zope instances + ZEO + Varnish) comfortably requires **8 GB RAM** across the stack.

<cite index="55-1,55-2,55-3">A Plone 6 install has two halves. The backend (Python + Zope + ZODB) serves the REST API and, if you choose Classic UI, full HTML pages. The frontend (Volto) is a React SSR app that consumes the REST API and renders pages.</cite> That split brings two deployment surfaces instead of one, and two independent release pipelines to coordinate.

Plone's `plone.app.caching` module provides granular control over Cache-Control headers and ETag generation, but configuring it correctly for authenticated vs. anonymous content requires deep familiarity with HTTP caching semantics. Varnish VCL configuration for Plone is non-trivial and platform-specific.

## Pricing and Total Cost of Ownership

Software licensing is a fraction of the actual cost. The real TCO delta between these platforms comes from engineering labor and infrastructure.

### October CMS Pricing

October CMS uses a license-per-project model:

| Plan | Cost | What You Get |
|---|---|---|
| **Free License** | $0 (1st year free, then $39/year for updates) | One project, full platform access, marketplace |
| **Single License** | $39/license | One project, one year of updates, extendable at $39/year |
| **Unlimited License** | $312/year (annual) or $360/year (monthly) | Unlimited projects, Partner Program access |

<cite index="28-26,28-27">Your license is perpetual. Non-renewal only removes access to the Update Gateway.</cite> October defines a website by identity rather than installation, so live, staging, and dev for the same branded site count as one site. Separate branded sites need separate licenses.

<cite index="28-20,28-21,28-22">Platform support is completely free for every license holder. You can reach them through their contact page, the community forum, GitHub and Discord.</cite> <cite index="28-23,28-24">Premium Support is a separate, optional consulting service for when you need hands-on help with your specific website or custom code.</cite>

### Plone Pricing

Plone is 100% free open-source software under the GPL. There are no license fees regardless of scale.

**But "free" is misleading without context.** Plone's real cost is operational:

- **Hosting:** Self-hosted only. Minimum 4 GB RAM for a basic production stack; 8 GB RAM for a clustered deployment. No shared PHP hosting.
- **Developer cost:** Plone developers command higher hourly rates than PHP/Laravel developers (typically $120–200/hr for senior Plone specialists vs. $80–140/hr for senior Laravel developers) because the talent pool is significantly smaller. The Zope Component Architecture has a steep learning curve.
- **Ops complexity:** Two deployment surfaces (backend and Volto frontend), ZEO clustering, Varnish configuration.
- **Extension model:** <cite index="11-8,11-9">You can't upload any extension through the admin UI. You'll need a developer who adds extensions to the buildout and manages the deployment.</cite>

### 3-Year TCO Comparison

The following estimates assume a small team (1–2 developers), a single project, and US-based contractor rates. Developer hours assume initial setup plus ongoing maintenance; infrastructure assumes self-hosted cloud VPS.

| Cost Category | October CMS | Plone | Assumptions |
|---|---|---|---|
| License | $39–117 | $0 | October: $39/yr renewal; Plone: GPL |
| Hosting (VPS/Cloud) | $600–1,800 | $1,800–4,320 | October: 1–2 GB RAM VPS; Plone: 4–8 GB RAM |
| Developer setup | $2,000–5,000 | $6,000–18,000 | October: 20–50 hrs @ $100/hr; Plone: 40–120 hrs @ $150/hr |
| Ongoing maintenance | $1,000–3,000/yr | $3,000–9,000/yr | October: 10–30 hrs/yr; Plone: 20–60 hrs/yr |
| **3-Year TCO** | **$6,000–$17,000** | **$17,800–$49,320** | |

> [!NOTE]
> Plone's higher TCO reflects specialized talent requirements and the operational overhead of the Zope/ZODB stack — not a licensing disadvantage. For organizations with existing Python teams and security-critical requirements, Plone's value proposition can outweigh the cost delta. An in-house Python team that already knows Zope effectively halves the Plone maintenance cost estimate above.

> [!WARNING]
> Do not compare these platforms on subscription price alone. October's cost center is usually custom PHP work plus licensed update access. Plone's cost center is specialized talent, decoupled frontend/backend operations, and heavier infrastructure. The developer rate difference ($80–140/hr for Laravel vs. $120–200/hr for Plone specialists) compounds over a 3-year engagement.

## Migration Paths: October CMS ↔ Plone

Migrating between these platforms is not a straightforward port. The data models are fundamentally different, and there is no automated tool that handles it end-to-end. Every migration requires custom transformation scripts, careful content mapping, and thorough validation.

### Migration Effort Sizing

Before estimating hours, classify the project by complexity. The following ranges assume experienced developers on both source and target platforms, working from clean source data:

| Project Scale | Definition | Estimated Effort |
|---|---|---|
| **Small** | ≤50 pages, 1–2 content types, no workflow, no file library | 40–80 person-hours |
| **Medium** | 50–500 pages, 3–8 content types, simple workflow, moderate file library | 120–300 person-hours |
| **Large** | 500+ pages, 8+ content types, multi-step workflow, per-object ACLs, large file library | 400–800+ person-hours |

> [!CAUTION]
> Do not size this project by page count alone. Page count is the least predictive variable. Size by: number of distinct content types, block/component patterns, workflow states, user and group mappings, file volume, rich text complexity, and redirect rules. A 50-page site with 8 custom content types, per-object permissions, and 2,000 managed files will cost more than a 300-page blog with one content type and no files.

### Migrating from October CMS to Plone

**Step 1: Export from October CMS.** <cite index="44-1,44-2,44-3,44-4">The `Backend\Behaviors\ImportExportController` class provides features for importing and exporting data. The Import page allows a user to upload a CSV file and match columns to the database. The Export page allows a user to download columns from the database as a CSV file.</cite>

For bulk extraction, query the relational database directly. October CMS uses standard MySQL/PostgreSQL tables you can dump with `mysqldump` or `pg_dump`. Content tables follow plugin-specific naming conventions (e.g., `october_blog_posts`). Tailor blueprints are YAML, but the data lives in generated tables and can include multisite behavior, translated fields, and file relations that need explicit mapping.

**Step 2: Transform.** Map relational rows to Plone content types. Each October CMS record must be converted into a JSON structure compatible with `plone.restapi`'s deserialization format. Key mappings:

- October CMS page → Plone Document or Page content type
- October CMS blog post → Plone News Item or custom Dexterity type
- File attachments → Plone File/Image objects
- Categories/tags → Plone taxonomy or Subject field

Rebuild presentation as **Plone types plus Volto blocks**, not as a blind HTML lift. Volto stores block data in `blocks` and `blocks_layout` JSON fields within the content object — October partials and Twig page files do not map 1:1 to these structures. Each Twig partial that generates content must be analyzed individually and reproduced as a Volto block type (text, image, listing, table, or custom).

**Step 3: Import to Plone.** Use `plone.restapi` to POST content programmatically. <cite index="50-2">plone.exportimport is shipped with Plone 6.1 and is a great package to export and import data from the same version.</cite> For cross-platform imports, the REST API is the preferred entry point.

```python
import requests

plone_url = "https://your-plone-site.com/++api++"
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
}

page_data = {
    "@type": "Document",
    "title": "Migrated Page Title",
    "description": "Imported from October CMS",
    "text": {
        "content-type": "text/html",
        "data": "<p>Your HTML content here</p>"
    }
}

response = requests.post(
    plone_url,
    json=page_data,
    headers=headers,
    auth=("admin", "password")
)
```

Define governance early. Plone can take you further on approval flow and role-driven publishing, but that only helps if the target workflow is modeled before the data load. Retroactively applying workflow states to imported content is possible but adds hours to the project.

### Migrating from Plone to October CMS

**Step 1: Export from Plone.** This is the harder direction because of ZODB. <cite index="50-1,50-2,50-3">The recommended tool is `collective.exportimport`. plone.exportimport is shipped with Plone 6.1, while `collective.exportimport` works with Plone 4, 5, and 6.</cite> <cite index="50-5">Both use plone.restapi to serialize and deserialize data, though the data format is slightly different since they serve different use cases.</cite>

Alternatively, use `plone.restapi` directly to GET all content as JSON:

```bash
curl -H "Accept: application/json" \
     https://your-plone-site.com/++api++/@search?portal_type=Document
```

Do not attempt to reverse-engineer the ZODB file (`Data.fs`) directly. It is a binary file of pickled Python objects. Attempting to parse it without the Zope application layer will produce unpredictable results, especially for content modified by multiple add-ons that extend the base types.

**Step 2: Transform.** Decide whether October is the target as Tailor blueprints, custom plugin models, or theme-driven pages — you need to choose the ownership model before you flatten Plone content into it. Key challenges:

- **Workflow states** have no direct equivalent in October CMS. You will need a custom status field or plugin.
- **ZODB object paths** (e.g., `/Plone/about/team`) must be converted to October CMS URL slugs.
- **Rich text** in Plone uses a different sanitization model — verify that HTML transfers cleanly.
- **File blobs** in ZODB need to be extracted and stored in October CMS's file attachment system.
- **resolveuid internal links:** Plone stores internal hyperlinks using a proprietary UID resolution system — links appear as `href="resolveuid/abc123"` rather than human-readable URLs. During extraction, every resolveuid reference must be mapped to its corresponding absolute URL using the `@resolveuid` REST API endpoint, or all internal linking will break in the target system. This is the single most commonly missed step in Plone exports.
- If the source uses **Volto**, treat blocks as structured data, not rendered HTML. Each block type (text, image, listing, table) is stored as a discrete JSON object in `blocks` and `blocks_layout`. You will be recreating this behavior in Tailor fields, partials, components, or custom code — there is no automatic block-to-template conversion.

**Step 3: Import to October CMS.** <cite index="41-4,41-5">Import and Export models define the logic used when processing the import or export action, extending the `Backend\Models\ImportModel` and `Backend\Models\ExportModel` models respectively.</cite> For large datasets, direct database insertion via Laravel Seeder classes or Artisan commands is faster than the GUI import. October CMS 4.3 can export and import file attachments as ZIPs with the actual binaries inside, which simplifies staged file migration.

> [!CAUTION]
> When migrating out of Plone, resolveuid link integrity is the most commonly missed step. Plone stores internal hyperlinks as `href="resolveuid/abc123"` — not as human-readable paths. Use the `@resolveuid` REST API endpoint to map each UID to its current URL before extraction. Any resolveuid reference that survives into October CMS will render as a broken link.

### Common Migration Pitfalls

1. **resolveuid internal link breakage (Plone → October).** Every internal link in Plone is stored as a UID reference, not a path. Unresolved UIDs in October CMS are broken links. Map every UID to its absolute URL during extraction using `@resolveuid`.
2. **Rich text divergence.** Plone stores HTML with portal transforms and link integrity checks. October CMS uses standard HTML in database text fields. Expect broken internal links and malformed markup unless you parse and remap during extraction.
3. **File reference remapping.** Plone stores files as ZODB blob objects with UID-based references. October CMS stores files on the filesystem with database pointers. Every file reference needs explicit remapping.
4. **Workflow state loss (Plone → October).** Plone's built-in workflow engine tracks publication state (private, pending, published) as a first-class data attribute. October CMS has no native equivalent — content status is typically a simple boolean or plugin-specific field. You must decide how to flatten or replicate workflow state before import.
5. **Permission flattening.** Plone's fine-grained permission model (per-object ACLs, role inheritance through folder hierarchy) does not translate to October CMS's role-based system. Expect significant permission redesign.
6. **URL structure changes.** Plone uses hierarchical object paths (`/site/section/page`). October CMS uses flat URL slugs. A redirect map is mandatory to preserve SEO equity.
7. **Volto block structure (Plone → October).** If the source site uses Volto, content is stored as JSON block arrays, not HTML. Each block type requires individual handling in the transformation layer.

### Migration Manifest Template

Before moving a single record, write the mapping down. A minimal manifest keeps the project honest and serves as the acceptance criteria document:

```yaml
contentTypes:
  - source: <source type>
    target: <target type>
    fields:
      title: <target field>
      body: <target field>
      files: <target field>
    volume:
      estimated_records: <count>
      estimated_files: <count>

richText:
  resolveuid_map: required  # Plone → October only
  html_sanitizer: verify

security:
  users: preserve | merge | reissue
  groups: preserve | redesign
  workflow: preserve | simplify | rebuild
  per_object_acl: flatten | rebuild  # Plone only

files:
  strategy: direct-copy | api-upload | staged-zip
  blob_extraction: required  # Plone only

urls:
  redirects: required
  source_path_pattern: <e.g. /Plone/section/page>
  target_slug_pattern: <e.g. /section/page>

qa:
  sample_size: 50
  baseline_snapshot: required
  reconcile:
    - record counts per content type
    - file counts and byte totals
    - internal link spot-check (50 random pages)
    - permission checks (10 representative objects)
    - workflow state verification (if applicable)

effort_estimate:
  scale: small | medium | large
  person_hours: <range>
  contingency: 2x–3x for cross-ecosystem migrations
```

## Platform Roadmaps

Understanding each platform's trajectory matters for migration timing and long-term commitment.

### Plone Roadmap

<cite index="9-6,9-7">Plone 6.2 was released in Q4 2025/Q1 2026. Security updates for Plone 6 will be provided through 2027 (five years after the release of Plone 6.0).</cite>

<cite index="8-1,8-2,8-3">The majority of sprint effort is now directed at Plone Aurora, the next-generation Plone frontend. Aurora has its own dedicated repository, and is based on React Router 7 (framework mode), the Quanta design language, and a modern add-on and registry system.</cite>

**The Volto → Aurora transition risk.** The Plone project has stated there is **no migration path from Classic UI back to Volto**, and the community direction is clearly toward Aurora as the eventual replacement for Volto. This creates a specific planning constraint for new deployments:

- Starting a new Plone deployment on **Volto today** means a future frontend migration to Aurora when it becomes the default, likely in the Plone 7 timeframe.
- Starting on **Classic UI** avoids the Volto investment but means building on a frontend that is no longer receiving primary development focus.
- The Aurora add-on system is not backward-compatible with Volto add-ons.

Organizations committing to Plone in 2025–2026 should factor this frontend transition into their 3–5 year TCO. A Volto-based Plone deployment will require a frontend re-platforming project before the end of Plone 6's security support window in 2027.

<cite index="9-14">Plone 8 is expected to be released in 2032 as the successor to Plone 7.</cite>

### October CMS Roadmap

<cite index="74-3,74-4,74-5,74-6,74-7">October CMS version 4 focuses on stability, modern tooling, and a better experience for developers. Powered by Laravel 12, the team worked to keep October-specific breaking changes to a minimum, so upgrading from v3 should be smooth.</cite>

<cite index="67-13,67-14">In January 2026, with October CMS v4.1, the project's built-in Ajax framework was extracted and released as an independent open-source package called Larajax. Larajax allows Laravel developers to call controller methods directly from HTML using a data-request attribute, without creating separate API routes.</cite>

October CMS 4.3 added ZIP-based file attachment export/import, which is directly useful for migration projects involving file libraries. The platform's alignment with Laravel's release cycle (Laravel 12 in 2025, Laravel 13 expected in 2026) means regular but predictable upgrade overhead.

## Decision Matrix

| Factor | October CMS Wins | Plone Wins |
|---|---|---|
| Setup speed | ✅ Minutes to production on shared PHP hosting | — |
| Security posture | — | ✅ Architecture-level protection; ZODB eliminates SQL injection class |
| TCO (small teams, 3 years) | ✅ Lower by 2–3x on comparable projects | — |
| Enterprise workflows | — | ✅ Native multi-step workflow engine with per-role transitions |
| Developer hiring pool | ✅ PHP/Laravel developer market is large and competitive | — |
| Government/compliance | — | ✅ Proven at FBI, UN, EU scale; no reported wild exploitation |
| Headless CMS capability | Possible (custom routes or plugins) | ✅ Native REST API (`plone.restapi`) with full content and workflow exposure |
| Plugin ecosystem breadth | ✅ Marketplace + Composer; simpler installation | — |
| Accessibility compliance | — | ✅ WCAG built into core UI |
| Data portability | ✅ Standard SQL; queryable with any database tooling | — |
| Multilingual governance | — | ✅ First-party i18n framework with workflow integration |
| Infrastructure simplicity | ✅ Single application, 1–2 GB RAM VPS sufficient | — |
| Per-object permissions | — | ✅ Folder-hierarchy ACL inheritance, first-class feature |
| CI/CD integration | ✅ Standard PHP pipeline; Git-tracked flat files | Requires coordinated dual-pipeline (Python + Node.js) |

**Choose October CMS if:**
- Your team is already proficient in PHP and Laravel.
- You want rapid prototyping and a CMS that behaves like a standard PHP project with familiar tooling.
- Your content model is site-specific rather than governance-heavy.
- Budget is constrained and standard PHP hosting (1–2 GB RAM VPS or shared hosting) is a requirement.
- You need relational data access for reporting, exports, and third-party integrations.
- CI/CD simplicity is a priority — one deployment surface, Git-tracked templates, standard Composer workflow.

**Choose Plone if:**
- Security is a non-negotiable top priority. <cite index="62-2">The CIA, FBI, the government of Brazil, municipalities in Italy and Belgium, many schools, universities, governments and businesses around the world have chosen Plone for secure, enterprise web content management.</cite>
- You need complex, multi-step publication workflows and granular per-object permissions that cannot be approximated by simple boolean status fields.
- Multi-language content management at institutional scale is a core requirement.
- <cite index="64-4">York College (CUNY) has run Plone across the main website, parking permits, digital ID, and faculty reappointment workflows for fifteen years.</cite> If long-term institutional stability matters, Plone's track record is hard to match.
- You have the budget (3-year TCO of $18K–$49K for a small team) and an existing Python team to support specialized Zope infrastructure.
- You understand and accept the Volto → Aurora frontend transition will require additional investment before 2027.

## Making the Migration Work

Whether you are moving from October CMS to Plone or the reverse, the core challenge is bridging a relational SQL datastore and an object-oriented ZODB. The five practices that determine whether a cross-ecosystem CMS migration succeeds or fails:

1. **Audit content types first.** Map every content type, field, and relationship on the source platform before writing any migration code. Discoveries made mid-migration are expensive.
2. **Prototype with a real dataset, not synthetic data.** Run 50–100 actual production records through the full pipeline before committing to the transformation approach. Production data surfaces encoding issues, unexpected field values, and edge cases that synthetic data never does.
3. **Resolve resolveuid before anything else (Plone exports).** Map every internal UID to its absolute URL using the `@resolveuid` REST endpoint before writing transformation logic. This cannot be patched after import without re-processing every affected record.
4. **Build your redirect map as part of the migration, not after.** URL structures will change. Redirect mapping is not post-launch cleanup — it is migration infrastructure. Missing redirects cost SEO equity that cannot be recovered retroactively.
5. **Budget 2–3x your initial estimate for cross-ecosystem migrations.** Same-ecosystem CMS migrations (WordPress to WordPress, Plone to Plone) are primarily schema-mapping exercises. Cross-ecosystem migrations between incompatible storage paradigms—like moving between [Notion and Webflow](https://clonepartner.com/blog/blog/notion-vs-webflow-architecture-tco-migration-guide/)—consistently take longer. The effort sizing table above provides baseline ranges, but the 2–3x contingency is not optional.

If you are deciding whether to run the cutover internally, our piece on [in-house vs. outsourced migration](https://clonepartner.com/blog/blog/in-house-vs-outsourced-data-migration/) covers the realistic cost and risk tradeoffs. If downtime is the blocker, read [Zero Downtime Data Migration](https://clonepartner.com/blog/blog/zero-downtime-data-migration/) before you plan the switch.

> Planning an October CMS ↔ Plone migration? Our engineers have moved data between incompatible architectures — including ZODB, MySQL, and proprietary APIs — without downtime. Book a free 30-minute scoping call.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

### Is October CMS or Plone more secure?

Plone has a stronger security track record by design. Its ZODB storage eliminates SQL injection entirely, and the Plone Foundation reports no serious vulnerability has ever been exploited in the wild. October CMS relies on Laravel's security features and standard relational database protections, which are solid but require careful configuration.

### Can I migrate content from Plone to October CMS?

Yes, but it requires custom transformation scripts. Plone stores data in ZODB (object-oriented), while October CMS uses relational SQL tables. Export content from Plone using collective.exportimport or plone.restapi as JSON, transform the data to match October CMS's schema, then import via Laravel seeders or October's ImportExportController.

### What database does Plone use?

Plone uses ZODB (Zope Object Database), an object-oriented database that stores Python objects as serialized pickles in binary format. Enterprise deployments can use RelStorage to store ZODB data in a relational database like PostgreSQL, but the data is still accessed through the ZODB API, not via SQL queries.

### Is October CMS open source in 2026?

Its source code is publicly available on GitHub again as of version 4.0, but production use still ties into October licensing for updates, Marketplace access, and support. New accounts get one free first-year project license; renewals are $39/site/year. A free open-source fork called Winter CMS exists for teams wanting a fully open-source model.

### How much does October CMS cost compared to Plone?

October CMS licenses start at $39/year per project (with a free first year). Plone is 100% free open-source software. However, Plone's operational costs are significantly higher due to self-hosted infrastructure, specialized Python/Zope developers, and more complex deployment. A 3-year TCO for a small team typically runs $5,700–$15,000 for October CMS versus $14,200–$39,600 for Plone.
