Expanding Mautic’s Data Model: Introducing Custom Tables

Hello,

Mautic has long empowered marketers with flexible data management through custom fields. These fields allow users to extend contact profiles with additional attributes tailored to their business needs. However, as use cases grow more advanced, the current model begins to show its limits—particularly when working with structured, repeatable, or relational data.

It’s time to consider the next evolution: custom tables.

The Limitation of Custom Fields

Custom fields are excellent for simple, flat data—text values, numbers, dates, and boolean flags. But modern marketing operations increasingly rely on more sophisticated data structures, such as:

  • Repeatable datasets (e.g., multiple purchases, interactions, or subscriptions)

  • Relational data between entities

  • Complex schemas coming from external systems

To work around these limitations, users often:

  • Overload contact records with duplicated or indexed fields, or

  • Offload structured data into external systems

Both approaches introduce friction, complexity, fragmentation and can hit database hard limits.

Introducing Custom Tables

Now imagine a system where users can create custom tables within Mautic, just as easily as adding a custom field—but with far greater flexibility.

This feature would allow users to define structured, relational datasets directly inside Mautic, linked to core entities like contacts, companies, or campaigns.

From Fields to Fully Custom Schemas

With custom tables, users wouldn’t just be adding data—they would be designing data models.

Users could create ever more complex schemas within Mautic, limited only by their imagination. What previously required a developer, external database, or middleware could now be handled natively within the platform.

This opens the door to:

  • Multi-layered relational data structures

  • Nested and repeatable records

  • Schema designs that mirror real business processes

In effect, Mautic would evolve from a system that stores marketing data into one that can model it with precision.

This feature would allow complex schemas—previously only achievable through custom development—to be built, managed, and leveraged directly within Mautic’s interface.

Key Capabilities

  • Custom Schema Definition
    Define tables, columns, data types, and relationships through an intuitive UI.

  • One-to-Many & Many-to-One Relationships
    Associate multiple records (e.g., orders, events, tickets) with a single contact or company.

  • Advanced Segmentation
    Build segments using conditions across related tables (e.g., “contacts with 3+ purchases in the last 30 days”).

  • Normalized Data Storage
    Eliminate cluttered contact records and improve data integrity.

  • API-First Integration
    Allow external systems to push structured, relational data directly into Mautic.

Real-World Use Cases

  • E-commerce
    Maintain full order histories, product relationships, and transaction data.

  • Event Management
    Track registrations, attendance, and engagement across multiple events per contact.

  • SaaS Platforms
    Store subscriptions, feature usage, and lifecycle data.

  • Custom Business Logic
    Model domain-specific processes such as applications, claims, or onboarding steps.

User Experience Considerations

To ensure adoption, the experience should remain as intuitive as custom fields:

  • A dedicated “Custom Tables” section in settings

  • Guided schema creation with validation and previews

  • Visual relationship mapping between entities

  • Query builders for segmentation and campaign logic

The goal is power without sacrificing usability.

Performance & Architecture

Supporting custom tables would require thoughtful design:

  • Optimized joins and indexing strategies

  • Efficient query execution for segmentation

  • Caching layers for performance at scale

  • Backward compatibility with existing field-based systems

While technically complex, this investment would significantly expand Mautic’s capabilities.

Why This Matters

Marketing today is driven by data depth, not just data points. The ability to model relationships, track histories, and reflect real-world complexity is essential for meaningful automation.

By enabling custom tables, Mautic could empower users to:

  • Build richer, more accurate customer profiles

  • Reduce reliance on external systems

  • Unlock advanced personalization and automation

  • Bridge the gap between marketing tools and full customer data platforms

Final Thoughts

Custom fields were a powerful foundation. Custom tables are the natural next step.

By allowing users to define and manage complex schemas directly within Mautic, the platform can evolve into a truly flexible, developer-friendly, and future-ready system—without losing its accessibility.

This isn’t just a feature upgrade. It’s a shift toward making Mautic a platform where any data model a developer can imagine can be brought to life—no compromises required.

Thanks

Hello,

Why Custom Tables Would Solve Real Mautic Limitations

In my previous post, I explored the idea of introducing custom tables into Mautic as a natural evolution beyond custom fields. In this follow-up, I want to focus on something more practical: the real problems this would solve.

This isn’t just a “nice to have” feature—it directly addresses limitations that many users, including myself, have already encountered.

The Hidden Ceiling of Custom Fields

From my perspective, one of the biggest issues with the current system is what happens when you scale.

Adding large numbers of custom fields to the contact table may seem fine at first—but eventually, you run into hard database limits on some databases engines.

  • Column limits: Most databases impose a maximum number of columns per table.

  • Index limits: The number of indexes is also finite, and Mautic relies heavily on indexing for performance.

As more fields are added, performance degrades, schema management becomes harder, and eventually, you simply can’t add more fields.

This creates an artificial ceiling on what should otherwise be a flexible system.


Custom Tables as a Structural Solution

Custom tables would fundamentally solve this problem by moving away from a single, overloaded contact table.

Instead of forcing everything into one structure, we could:

  • Distribute data across multiple purpose-built tables

  • Define relationships rather than duplicating fields

  • Keep schemas clean, efficient, and scalable

This isn’t just about flexibility—it’s about long-term sustainability of the data model.

Moving Beyond Custom Object Plugins

There have been attempts to address this problem through plugins that have yet to be released, such as custom object solutions. While helpful, they inevitably come with limitations:

  • Restricted flexibility compared to native features

  • Dependency on plugin maintenance and compatibility

  • Constraints imposed by plugin architecture

Rather than relying on workarounds, it would be far more powerful to make this a core capability.

No need for a custom object plugin—just allow users to create custom tables and define relationships directly within Mautic.

Build Your Own Schema

One of the most compelling advantages of this approach is freedom.

Users could design their own schema to match their exact business needs:

  • Simple extensions for lightweight use cases

  • Complex relational models for advanced implementations

  • Structures that align with external systems and data pipelines

In short, we move from “working around Mautic’s structure” to defining our own.

Table Prefixing & Clean Separation

In my own setup, I already use table prefixes to organize and manage data more effectively. Extending this concept to custom tables would be incredibly useful.

Custom tables could:

  • Use a separate prefix (or multiple prefixes)

  • Be clearly distinguished from core Mautic tables

  • Remain isolated for easier maintenance, backup, and migration

This separation would also reduce risk, making it easier to manage upgrades and troubleshoot issues without interfering with core functionality.

A More Scalable Future for Mautic

Ultimately, this comes down to scalability.

Right now, pushing Mautic beyond certain limits requires compromises—either technical workarounds or external systems. Custom tables would remove that friction and allow the platform to scale more naturally with real-world use cases.

Final Thought

From my perspective, custom tables wouldn’t just enhance Mautic—they would resolve fundamental architectural constraints that users are already hitting today.

Instead of stretching the current system to its limits, this approach gives us a way to expand it cleanly, logically, and sustainably.

And perhaps most importantly, it puts control back where it belongs: in the hands of the user.

Thanks

Why not turn Mautic Forms into ‘custom tables’ ?

Hi, how would this solve OPs issue? As far as I understood, OP would like an enhanced database model for his use case.

In general, there is a lack in flexibility in I think all marketing automation software and imo the problem with all marketing automation software I know is that it’s trying to be something it shouldn’t. And almost always it is piggybacking a CRM on top of a halfway finished automation layer. What people tend to forget is the difference in nature between a CRM and Marketing Automation Software. A CRM is always state driven while Automation is event driven. And state can be found everywhere. For some it lies in a spreadsheet, for others in enterprise software. But Marketing Automation only cares about a subset of the state and eventually it only cares about some state changing events that impact marketing. While I see use cases for OPs suggestion, e.g. holding information about all webinars a contact plans to visit, we should ensure that changes actually improve automation rather than just dumping data into Mautic.

Hello joeyk,

Yes, using forms to effectively create custom tables is an intriguing idea, and it’s something I plan to explore. That said, I see it as a short-term workaround at best—but I do appreciate the suggestion and and effort.

Mautic as a concept is wonderful. However, from a database perspective, its schema is quite limiting due to its largely flat design. I won’t revisit all the points I’ve already raised, but this constraint becomes increasingly apparent as implementations grow in complexity.

At present, I don’t have the Symfony expertise required to implement custom tables within Mautic myself. That said, for experienced developers working within the platform, this would likely be a relatively straightforward enhancement—one that could benefit the entire community. I’m also not suggesting this needs to be a paid feature; it feels like a natural evolution of the core platform.

In the short term, I can extend Mautic’s schema externally using SQL and other programming approaches. This allows me to build a more efficient and scalable data structure without interfering with Mautic’s core functionality or upgrade path.

As my experience with Symfony improves, I would certainly consider contributing toward implementing custom tables directly within Mautic in the future. User can then choose to use Mautic as is or add custom tables. It becomes end user choice and not limited by Mautic.

The goal of raising this feature request is simply to open the discussion. Ideally, it resonates with a developer who sees the value and is in a position to implement it.

Until then, extending the schema externally provides a workable interim solution—one that maintains compatibility while addressing current limitations.

I hope the developer community sees and acknowledges the power and freedom this feature would give to end users, and takes a serious look at implementing it—perhaps in small, incremental steps until it is fully realised.

Thanks for taking the time to read through the idea—I appreciate it’s quite a detailed one.

Hello dband,

To give a practical example of the limitation:

We currently sell at least ten different products, each with its own subscription start and end date. In the future, we’re likely to expand this to twenty or more products.

From a marketing perspective, I want to:

  • Send emails based on the specific product a contact has purchased

  • Trigger campaigns when a subscription is nearing expiry

  • Automatically promote more advanced versions of the same product during an active subscription

This requires a structured, repeatable dataset—essentially a list of subscriptions per contact, each with its own attributes (product type, start date, end date, status, etc.).

This is not something that can be cleanly or sustainably implemented using custom fields on the contact record.

Attempting to do so would mean:

  • Creating multiple fields per product (e.g., product1_start, product1_end, product2_start, etc.)

  • Continuously adding more fields as new products are introduced

  • Rapidly approaching database column and index limits

  • Experiencing degraded performance due to excessive indexing and table size

In short, the flat structure forces a solution that does not scale.

What this scenario really requires is a separate, related table of subscriptions, where each contact can have multiple associated records. This would allow:

  • Unlimited products without schema bloat

  • Clean querying for segmentation and automation

  • Efficient indexing and better performance

  • A far more natural representation of real-world data

There are already signs within the community that these limits are being reached. For example, I’ve seen a user exploring a move to PostgreSQL after hitting hard database limits in MariaDB—largely due to the constraints imposed by the flat schema.

However, the underlying issue isn’t the database technology itself. Switching databases may delay the problem, but it doesn’t resolve it. The real solution is to allow the schema to be extended properly, so that these hard limits are not encountered regardless of the database being used.

This approach aligns with well-established database design principles—normalisation, relational modelling, and separation of concerns—which are standard topics in university database courses and widely covered in software engineering literature.

This example highlights why custom tables are not just a “nice feature,” but a necessary step toward making Mautic scalable for more advanced and realistic use cases.

Thanks

Hello dband,,

Here is another example:

Tags Stored as JSON: A Structural Limitation

Another area where Mautic’s data model shows its limitations is in how tags are stored.

Currently, tags are held in a JSON structure rather than a properly normalised relational model. While this offers some flexibility, it creates real issues as data grows.

  • Poor query performance – JSON fields are harder to index, leading to slower segmentation and filtering

  • Limited scalability – performance degrades as the dataset increases

  • Lack of structure – difficult to extend tags with additional attributes or relationships

  • Breaks standard design principles – bypasses normalisation and relational integrity

Tags are a core part of segmentation and automation, so these limitations have a direct impact on real-world usage.

A Better Approach

A relational structure (e.g., tags and contact_tags tables) would allow:

  • Fast indexed queries

  • Clean many-to-many relationships

  • Greater flexibility and extensibility

More importantly, the introduction of custom tables in Mautic would naturally enable this approach.

Users could define their own relational tag tables, tailored to their needs, resolving many of these limitations without being constrained by the current JSON-based implementation.

Final Thought

This is another example where moving toward a more relational, extensible schema—supported by custom tables—would significantly improve performance, scalability, and flexibility within Mautic.

For those who want simplicity they don’t have to use custom tables. For those sunning at scale custom tables gives them endless options to expand the schema and make it more efficient in any way they choose.

Set Mautic free and allow end users to use the enormous power of relational databases by implementing custom tables

Thanks

Hi, I partially agree :slight_smile: one would have to decide what to index and what not, which would be a problem on its own.

Also, your use case to detect subscription end of life does not only need an enhanced data model but also segment rework.

I don’t like extensive data models because they are not solving any problems in a marketing system. At least, if it’s not used as a CRM. Such a system should rely on trigger points and not recalculating segment state every few minutes based on CRM fields. That’s why we started using external triggers to cluster contacts and use Mautic to focus on campaign delivery.

I am with you on improving performance of tags though, if needed. I never looked at how they are implemented. These are the backbone of Mautic and we make heavy use of them.

Hello dband,

I don’t want to repeat what I’ve already said, but to summarise:

Custom fields in Mautic can only be added to contact and company records.

The number of custom fields you can add to a given table is limited. In MariaDB, it’s been suggested this is around 50–60 fields. There are claims this limit could be higher with alternative databases like Progress SQL, but the exact limits are unclear.

More importantly, expanding contact and company tables to that extent introduces significant performance issues. As tables become wider, you quickly lose the ability to add indexes effectively, which leads to serious database performance degradation.

Wide table designs are generally considered poor practice in modern database architecture and are typically avoided. However, Mautic continues to rely on this schema model.

If Mautic supported custom tables and allowed custom fields within those tables, many of these limitations could be avoided through better schema design. In that scenario, performance would scale more naturally with server resources rather than being constrained by the schema itself.

As it stands, the Mautic UI does not support building complex segment rules. I’ve suggested improvements in the past, but these haven’t gained much traction. That said, there is a low-cost plugin available which allows you to run SQL queries against Mautic (and custom) tables and return contact_id values for segmentation.

In practice, this means I can already create custom tables directly in SQL and use that plugin to build highly complex segments based on any query I design. So the functionality I need is achievable today outside of Mautic.

I had hoped to encourage the developers to improve the segment rule builder and support custom tables natively. However, at this point, it feels unlikely this will happen—if there were intent to address the underlying database design, it likely would have been done long ago.

Ultimately, the constraint is Mautic’s architecture, which remains under the control of its developers, rather than any limitation of the database technology or server hardware.

Thanks

I understand. Ultimately you have to agree though, that you turn this system into a full CRM with Marketing Automation capabilities.

At this point, you have Hubspot (light). I would like to move the other direction; ditch most of the custom fields and just keep what’s necessary to identify a contact and it’s marketing relevant stage. Everything else is triggered externally.

There are good CMS systems like directus.io (not affiliated) which could be used as a data layer. It took them years to build a stable solution for custom data models.

Apart from the data model issue I would also question the approach of rebuilding complex segments in intervals. Especially larger systems (which you are referring to) should rather recalculate contact state on change and thus decide if a contact drops out of a segment or not.

Talking about data, Mautic feels bulky. And I believe adding a more extensive data mode wouldn’t simplify anything. It will solve some problems, I agree, but it would hurt maintainability. At this point, I feel, that we should remove as much as possible from Mautic core and break leftover modules into plugins via contracts to enable automation.