Inside our process.
No spin. No hidden hours.

A transparent look at how Open edX features get built — what a “small” change actually costs, why architecture drives the hours, and the methodology behind our estimates. Built from production work on the n8n Academy platform.

10 repos · 6 envs · 1 platform
Authored by Raccoon Gang
Real ticket · n8n-297
09:14SlackClient: "make the Discussions font a bit bigger"
09:18TriageRepos affected: 3 · Risk: low · MFE + Legacy
09:42DesignToken bump 14 → 15 in Paragon theme
10:30Backendtutor-contrib-rg-conf · feature flag added
11:55Frontendfrontend-app-discussions · MR opened
13:20Themetutor-contrib-rg-theme · dark + light pass
14:05DevOpsTutor plugin v2.4.1 → tutor-deployment
15:10QADev + Stage smoke · regression suite green
16:24ReleaseTagged. Demo Friday.
shipped 16:24
Why these numbers

The methodology
behind our estimates.

Our hours aren’t intuition. They come from a structured process honed across dozens of Open edX deployments — and from observing where production work diverges from local development.
73design tickets

Decomposed into 12 components, each touching 2–4 repositories.

6repositories per release

Synchronized tagging across edx-platform, theme plugin, conf plugin, brand-openedx, MFE forks, and tutor-deployment.

2stacks per visual change

MFE (React) + Legacy (Django templates) duplication until upstream migration completes.

The rest of this page shows the architecture and process that produce these numbers — and lets you build estimates yourself.

Part 1 — Anatomy of an Open edX feature

When you say “just make the font bigger,”
here’s what actually happens.

Twelve concrete steps. Each one has a name, a person, and a paper trail. The reason a “simple” request rarely takes an hour is not estimation drift — it’s the underlying architecture of Open edX itself.
Triage
scope · risk
Investigation
POC · spike
Design
Figma if visual
Backend
Django plugin
Frontend
MFE component
Theme
tutor-contrib-rg
Tutor
plugin · config
DevOps
build · deploy
Manual setup
waffle flags
QA
test · regression
Review
MR cycles
Release
tag · prod
Real example · n8n-275

“Fix Notifications link in Account Settings”

From your side: a broken link, should take an hour.
Estimated 10h. Actual 20.75h. Why? The upstream bug ran deeper than the surface symptom — it touched account settings, MFE config, and theme rendering at once.

Open edX is not one codebase. It’s ten.

We maintain forks of edx-platform, tutor-contrib-rg-conf, tutor-contrib-rg-theme, frontend-component-header, frontend-component-footer, frontend-build, frontend-app-account, platform-extensions, brand-openedx, and your dedicated programs-catalog service. A “small” UI change often spans three or four of these.

breakdown.tsv
01
Investigation
Why does the link go nowhere? Default Open edX bug in Teak release
1h
02
Decision
Patch upstream behavior via plugins, don't fork core
0.5h
03
Backend
Config changes in tutor-contrib-rg-conf · 2 MRs
4h
04
Frontend
Forks of frontend-app-account (2 MRs) + frontend-build (1 MR)
4.5h
05
Theme
Adjustments in tutor-contrib-rg-theme · 2 MRs
2h
06
DevOps
Updated tutor-deployment for new plugin versions
1.5h
07
edx-platform
Single commit fixing core behavior
1h
08
Manual setup
Waffle flag config on dev, stage, prod
1.5h
09
QA
Test on all three envs, dark + light mode
2h
10
Review + bugfix
Internal cycles
2h
11
Release
Tagging, deploy, smoke test
0.75h
Total6 repositories touched20.75h
Part 2 — Architecture

Every theme change is double work by definition.

Open edX is mid-migration from Legacy Django templates to MFE (React micro-frontends). Both stacks exist on your platform — different pages use different ones. This is upstream architecture. The foundation is migrating over the next 2–3 releases.
learn.n8n.io
Legacy
learn.n8n.io
Django templates
MFE
apps.learn.n8n.io
React micro-frontend
Shared design tokens
Paragonrg-themebrand-openedxdark mode
Legacy stack
Django templates · Mako · Sass
  • Course content
  • Studio admin
  • Some checkout flows
  • Legacy survey blocks
MFE stack
React · Paragon · webpack
  • Learner dashboard
  • Profile · Account
  • Learning experience
  • Discussions · Communications
What this means for your invoice

A change to the dark theme toggle, the header avatar, or a typography token must be applied twice — once in Legacy templates, once in React MFEs. It’s why we invested in tutor-contrib-rg-theme early: it now shares Paragon design tokens between both, and the same investment will keep paying down in Phase 2.

Part 3 — Try it yourself

Build your own estimate.
Type dev hours. See the full cost.

Type the development hours you think a piece of work takes. The calculator auto-expands them into the full project cost using our updated dev-time overhead coefficients plus project-level PM and communication multipliers. Every line is editable so you can model your own scope.
Your development estimate

The dev hours you already have in mind — pure coding time, excluding everything else. Dev-time overhead lines below are computed as a percentage of this number.

hours of development
Dev-time overhead% of devHours
Testing
0.3 coefficient on dev time for QA testing and validation.
%
6.00h
Review
0.1 coefficient on dev time for review work before hand-off.
%
2.00h
Demo to QA
0.125 coefficient on dev time for walking QA through the change.
%
2.50h
Unit testing
0.2 coefficient on dev time for developer-owned unit test coverage.
%
4.00h
Bug fixing
0.1 coefficient on dev time for fixes found in the normal dev cycle.
%
2.00h
Code review
0.1 coefficient on dev time for code review cycles.
%
2.00h
Tech lead
0.2 coefficient on dev time; reduced to the minimum for this task.
%
4.00h
Bugfix
0.15 coefficient on dev time for post-review / QA bugfix work.
%
3.00h
Sum of overhead127.5%25.50h
Release activities

Fixed release work. Default uses the low end of the 2–4h per role / release range.

hours
Project management

Added on top of dev time, dev-time overheads, and release activities.

% → +4.75h
Team + project communication

Added as a percentage of the running total after PM is included.

% → +15.68h
Productive time

Optional. Drop below 1.0 to pad for meetings, context switches, async waits. Off by default — already baked into the category percentages above.

→ ÷ 1.00
Timeline risk

Optional. Push above 1.0 for unknown integrations or new architecture. Off by default — design changes against a locked Figma usually don’t need it.

→ × 1.00
Full estimate
67.9h
$5,434
@ $80 / hour
Dev → project multiplier
×3.40

Every 1h of dev expands into 3.40h of project work once the full process is counted.

Calculation
Dev20.00 h
Dev-time overhead 127.5%+25.50 h
Release activities+2.00 h
= Subtotal47.50 h
PM 10%+4.75 h
= With PM52.25 h
Team + project communication 30%+15.68 h
= Process total67.92 h
Total67.92 h
Added work by line
Testing6.00 h
Review2.00 h
Demo to QA2.50 h
Unit testing4.00 h
Bug fixing2.00 h
Code review2.00 h
Tech lead4.00 h
Bugfix3.00 h
Release activities2.00 h
Project management4.75 h
Team + project communication15.68 h

Default coefficients use the updated RG model: dev-time overheads are calculated from pure development hours, release activities are fixed hours, PM is added as 10% on the subtotal, and team / project communication is added as 30% on the total after PM. The productive-time and timeline-risk multipliers stay off by default; push them above/below 1.0 only for projects with unusual integration or staffing risk.

Part 4 — Phase 1 data

What the production work
looked like.

Two datasets from Phase 1 — the change request log and the communication cadence. Both show where small-looking work meets the multi-repo reality of Open edX.
A

Polish-on-the-fly change requests

11 tracked change requests during Phase 1. Each fully decomposed, estimated, and shipped. The variance between estimated and actual reflects the multi-repo nature of small Open edX changes.

#Change requestEstActual
134
Enroll button wording for Invite Only
n8n-134
5h1.25h
225
Add n8n-demo component into header
n8n-225
16.5h14h
268
Navigation links size
n8n-268
2h8.25h
275
Fix Notifications link in Account Settings
n8n-275
10h20.75h
Why small CRs sometimes overrun: a “font size” change can touch the same theme plugin, frontend component, and Legacy template that any structural change would. The minimum cost per CR is set by the architecture, not by the visible size of the request.
B

Communication intensity

Phase 1 logged 198 hours on communication against an estimated 92. The structured cadence below reflects the rhythm Open edX projects with active client involvement actually require.

Slack triage
Async · same-day
Weekly status
30 min · Mondays
0.5h
Sprint demo
Bi-weekly
1h
Strategic review
Monthly
1h
Why these hours exist

In T&M projects, communication hours are part of the work product, not overhead. Each item — triage, status, demo — produces decisions that affect what gets built next.

FAQ

Technical questions,
answered.

Common questions about Open edX architecture and our estimation methodology.
It’s the architecture of the platform itself. Open edX started as a Django monolith but has been splitting into microservices and micro-frontends over the past four years. The community maintains ~30 core repos; we maintain ~10 forks for your specific customizations. This is normal for enterprise LMS deployments — and unavoidable given upstream design.