AWS Big Data Blog

How Moovit achieved 33% cost optimization through architectural modernization

Moovit, part of Mobileye (Nasdaq: MBLY), is a leading Mobility-as-a-Service (MaaS) solutions provider and the creator of a leading urban mobility app. Moovit’s iOS, Android, and web apps offer users a smart mobility experience to get to their destination using any mode of public and shared transportation. Transit riders can benefit from mobile ticketing to plan, pay, and ride with transit services. Introduced in 2012, Moovit now serves over 1.7 billion users in more than 3,500 cities across 112 countries, in 45 languages.

Behind these user-facing experiences is a data platform that processes large volumes of mobility, application, and operational data to support product analytics, business intelligence (BI), monitoring, and data science. As the platform grew, Moovit needed to keep analytical workloads reliable and cost-efficient without slowing down teams that depend on fresh data every day.

Over several years, Moovit’s Amazon Redshift cluster grew continuously. It started with an expanding fleet of DC2 nodes, migrated to RA3 nodes, and scaled multiple times to keep pace with growing data demands, ultimately becoming the backbone of their entire data platform.

To address this growth, Moovit transformed their data architecture by building an optimal multi-engine lakehouse architecture and assigning each workload to the most suitable option. This modernization reduced their Amazon Redshift cluster by 50 percent, while establishing a flexible, multi-engine architecture ready for future use cases.

In this post, we share how Moovit gained visibility into workload patterns, cleaned up unnecessary load, selected candidates for offloading, and ran a successful proof of concept (POC) on Amazon EMR Serverless. Moovit ultimately divided the workload between multiple engines, building a modern and cost-optimized data platform that combines provisioned Amazon Redshift, Amazon Redshift Serverless, and Amazon EMR.

The challenge: Outgrowing a single-engine data platform

The Amazon Redshift engine handled a wide variety of workloads, including:

  • Heavy ETL processing: Raw data ingestion from Amazon Simple Storage Service (Amazon S3) followed by complex aggregation pipelines (daily user-aggregation running once per day with a 3-day lookback, and weekly 10-day-lookback jobs).
  • Near-real-time operational monitoring: Queries executing every 20 minutes against raw data for system-health dashboards.
  • Business-intelligence reporting: Tableau extracts and live dashboards.
  • Data-science workloads: Exploratory analysis and model-feature engineering.
  • Ad-hoc analysis: Non-recurring queries done by analysts and engineers.

With business growth, storage grew by orders of magnitude over the past decade as the platform expanded. All these varied workloads competed for the same engine and pushed it to its limits. Jobs experienced increasing queue times, service level agreements (SLAs) were at risk, and adding nodes provided minimal performance gains, creating a need to isolate workloads.

Gaining visibility: Measuring workload impact

Moovit’s first modernization milestone was to create a trusted measurement foundation before changing any workloads. Instead of treating warehouse activity as a single opaque stream, the team implemented automated query attribution that continuously classified each query by workload owner and execution context. The classification combined multiple signals: who executed the query (user or service account), recognizable query-signature patterns, and metadata emitted by orchestration frameworks and scheduled processes.

This produced a historical, query-level map of platform usage that answered three critical questions: who is generating load, what kind of workload is running, and how expensive each workload is in runtime and resource terms. With that baseline in place, the team made offload decisions from evidence rather than assumptions. This approach prioritized the largest and most stable optimization opportunities first and reduced the risk of moving business-critical workloads without visibility.

These classifications and workload metrics were reflected in a Tableau report that aggregated query activity by classification label and execution context. The view exposed operational dimensions such as classification, time granularity, service class, execution-time bucket, unload flags, and sample-query context, supporting both trend monitoring and root-cause drill-down.

The worksheet was parameterized to support multiple measurement modes over the same grouped workload population: total execution time, execution plus queue time, total CPU time, average execution time per query, and ratio-based efficiency views (execution/CPU and CPU/execution). This let the team compare “heavy by volume” workloads against “inefficient by behavior” workloads without creating separate artifacts.

For decision-making, CPU time was used as the primary impact metric because it best represented sustained compute pressure. Execution time, queue time, query-count normalization, and workload-management segmentation were treated as secondary evidence to distinguish:

  • compute-heavy but healthy workloads
  • queue-constrained workloads
  • high-frequency/low-cost workloads
  • noisy or weakly classified workloads that required attribution cleanup first

Using this framework, prioritization became systematic: first improve classification coverage, then rank workloads by CPU contribution, then validate with queue and workload management (WLM) signals, and finally choose the action path per workload (optimize SQL, reschedule, isolate, retire, or move to another engine).

The following figure shows an example of one of the dashboard widgets (CPU time by query).

Dashboard widget showing CPU time consumed by each query

Figure 1: CPU time by query, highlighting the most resource-intensive queries and their usage patterns

Cleanup: Reducing unnecessary data warehouse load

With a long-running data platform, in most cases the workloads will start accumulating, some of which become irrelevant at some point. For example, a report which was created and scheduled, yet it became irrelevant after a few years, but still running since no one disabled it. It’s important to indicate these workloads in general to reduce unnecessary load, yet even more critical before doing any significant architectural changes or migrations. Before migrating any workloads, Moovit first reduced unnecessary warehouse load.

The team:

  • Removed unused processes that were still consuming cluster resources.
  • Reduced unnecessary frequency where possible: some jobs ran more often than downstream consumers needed.
  • Reviewed workload-management guardrails to verify resource allocation matched actual priorities.

This cleanup phase was a prerequisite to migration. By removing waste first, the team verified that the workloads eventually selected for offloading were genuinely heavy rather than simply unoptimized or unnecessary.

The no-longer-relevant processes consumed around 7 percent of overall CPU time and were removed before the optimization work began.

Workload selection: Choosing what to offload

With a clear picture of workload patterns, Moovit faced a common decision point: continue scaling the existing Redshift cluster, or re-architect towards a multi-engine approach. The team evaluated two main paths:

  1. Re-architect with Redshift multi-cluster and data sharing: Identify workloads that could benefit from resource isolation, then redistribute processing and queries between multiple Redshift clusters, combining both serverless and provisioned options. This would redistribute load across use-case-optimized clusters and potentially save costs through better resource use.
  2. Re-architect with purpose-built engines: Identify workloads that could benefit from alternative processing frameworks and offload them to more suitable engines. This would reduce pressure on Amazon Redshift while building a more flexible, cost-efficient architecture.

Moovit decided to do both, because while some workloads benefited from being offloaded, others benefited from isolated Amazon Redshift compute.

The measurement data revealed a primary candidate for offloading: raw-data aggregation pipelines. This workload loaded raw data into Amazon Redshift from Amazon S3, then performed heavy sessionization and aggregation transformations. Raw tables were still used for ad-hoc and exploratory analysis, but recurring production consumers primarily depended on aggregated outputs, making these transformations strong candidates for offloading.

Proof of concept: Offloading to EMR Serverless with Spark SQL

With target workload identified, Moovit initiated a POC using Amazon EMR Serverless with Spark SQL. The choice of EMR Serverless was driven by several factors:

  • Spark SQL compatibility: The existing Redshift SQL logic could be ported with minimal changes to Spark SQL syntax.
  • Serverless simplicity: No cluster-management overhead during the evaluation phase.
  • Data-lake native: Processing could occur directly on data in Amazon S3.

The POC defined quantified success criteria measured over five or more consecutive runs:

  • Runtime reduction: Greater than or equal to 40 percent reduction for the transform portion of selected pipelines.
  • Amazon Redshift cost reduction: Greater than 30 percent reduction in Redshift RA3 compute with no performance degradation for remaining workloads.
  • Data-quality parity: Exact match between Spark and Amazon Redshift outputs on row counts, distinct users, and all published metrics over a frozen parity window.

Overcoming initial performance challenges

The first POC attempts exposed significant challenges. Early Spark jobs with 100 executors took approximately 4 hours, far exceeding the 30–40-minute baseline on Amazon Redshift. Beyond raw performance, the team encountered memory pressure, data-parity gaps between Spark and Amazon Redshift outputs, and subtle SQL behavior differences between the two engines.

The team systematically diagnosed and resolved these issues:

  1. Execution-plan analysis: Reviewing the Spark execution plan revealed suboptimal query patterns that generated excessive data shuffles.
  2. Query rewrites: Rewriting specific SQL constructs to align with Spark’s distributed processing model, including splitting large monolithic logic into staged transformations.
  3. Reducing or rewriting expensive DISTINCT patterns: Identifying and eliminating unnecessary DISTINCT operations that created heavy shuffle pressure.

After applying these optimizations, execution time dropped from 4 hours to approximately 10 minutes, and the required executors dropped to fewer than 50, surpassing the original performance.

Validation: Ensuring data parity before cutover

Before transitioning any workload to production, Moovit implemented a rigorous validation process. The new Spark output was compared with the previous Amazon Redshift output using multiple dimensions:

  • Row counts: ensuring no data was lost or duplicated.
  • Distinct users: verifying entity-level completeness.
  • Metric parity: all published business metrics matched.
  • Daily trends: time-series patterns remained consistent.
  • Row-level checks: spot-checking individual records for correctness.

Only after all validation checks passed consistently over multiple consecutive runs did the team proceed with cutover for each workload.

Moving to production: Expanding workload offloading

With a successful POC demonstrating both performance gains and cost savings, Moovit progressively moved additional workloads from Amazon Redshift to EMR:

  • Heavy-aggregation jobs: The primary daily and weekly aggregation pipelines transitioned fully to EMR.
  • Data-transformation stages: Preprocessing steps that previously consumed Redshift compute moved to Spark, with only final aggregated results loaded back into Amazon Redshift for BI consumption.
  • Weekly batch workloads: Large batch jobs that previously created resource contention during weekend processing windows.

The transition used a measured approach: each workload was migrated individually, with data-quality validation confirming parity before decommissioning the equivalent jobs which were running on Redshift.

Additional optimizations: Redshift Serverless, workload isolation, and Amazon EMR on Amazon EC2

Beyond EMR offloading, Moovit implemented further architectural improvements to isolate workloads and optimize costs.

Amazon Redshift rightsizing: Iterative cluster optimization

With heavy workloads successfully offloaded and isolated, Moovit proceeded to right-size the Redshift cluster. Rather than a single resize, the team reduced the cluster incrementally, two nodes at a time, using elastic resize. At each step, they validated that:

  • Existing BI workloads maintained acceptable performance.
  • Queue wait times remained within SLA thresholds.
  • No workload degradation was observed under peak loads.

This iterative approach minimized risk and allowed the team to find the optimal cluster size with confidence.

Workload isolation with Redshift Serverless

Amazon Redshift persisted as the engine of choice for serving curated BI data. However, not all Amazon Redshift workloads needed provisioned capacity:

  • Ad-hoc analyst queries: Moved to Redshift Serverless, isolating unpredictable workloads from the provisioned cluster through data sharing.
  • Data-science workloads: Transitioned to Redshift Serverless for flexible exploration without impacting production.

This workload isolation through Redshift Serverless provided resource separation without requiring additional provisioned capacity. The architecture now used data sharing to provide a unified view across provisioned and serverless clusters.

Operational isolation refinements

Moovit also refined workload isolation by rebalancing WLM priorities on the provisioned cluster. Because the ETL queue mainly handled raw data loading from Amazon S3 (which was not the bottleneck after heavy aggregations moved to Spark), its priority was reduced. At the same time, with most human users moved to Redshift Serverless, Tableau serving workloads on provisioned Redshift were prioritized higher to keep dashboard performance predictable. The final result: a 50% reduction in provisioned Redshift capacity.

Transitioning to EMR on EC2

EMR Serverless proved efficient for the POC phase: it allowed fast iteration without cluster management overhead. However, for longer-term recurring production workloads, Moovit moved to EMR on EC2 to better fit their production cost and infrastructure model, using existing compute reservations.

The transition between EMR deployment options required zero application code changes, demonstrating the flexibility of the EMR deployment options.

AI-assisted SQL translation

Additionally, Moovit used AI-assisted development tools, Claude Code and Cursor, to accelerate parts of the SQL transition process. These tools helped engineers identify Redshift SQL and Spark SQL syntax differences, suggest rewrites, and debug migration issues, while validation and production approval remained under engineer review.

Results: A modern multi-engine architecture

The architectural modernization delivered measurable outcomes:

  • Cluster size reduction: Redshift cluster size reduced to 50 percent of the initial capacity.
  • Performance improvement: Key aggregation jobs ran faster and more consistently on EMR (50 percent execution time reduction for p90).
  • Workload isolation: No single workload type could impact others through resource contention.
  • 33 percent overall data pipeline cost reduction: Combined savings from cluster reduction, transition to EMR, and efficient serverless usage.
  • Future flexibility: The multi-engine architecture provided pathways for additional use cases without architectural changes.

The following figures compare aggregation-job performance before and after the transition.

Chart comparing aggregation-job execution times before and after the transition, with longer, inconsistent runtimes before and shorter, stable runtimes after

Figure 2: Aggregation-job execution times before and after the transition

Chart comparing wall-clock time for job executions across percentiles, with p90 at 5.48 hours before the transition and 2.77 hours after

Figure 3: Wall-clock time for job executions by percentile, before and after the transition

The resulting architecture assigned each workload to the engine that fits it best:

Workload type Engine Rationale
Heavy ETL and aggregation Amazon EMR (Spark SQL) Distributed processing on Amazon S3. No data warehouse load required
Ongoing processing and BI reporting Amazon Redshift provisioned 24/7 running processes
Ad-hoc queries Amazon Redshift Serverless Burst capacity with workload isolation
Data science Amazon Redshift Serverless Flexible exploration without impacting production

Lessons learned

The Moovit modernization journey produced several key insights applicable to similar architectural transitions:

  1. Measure before you move: Establishing baseline metrics and automated classification was essential for identifying true offloading candidates. Without granular workload-level measurements, the team would not have identified which specific processes were exhausting the cluster.
  2. Clean up before you migrate: Reducing unnecessary load first verified that migration efforts targeted genuinely heavy workloads rather than simply unoptimized or unused processes.
  3. Small SQL changes, big impact: Moving from Redshift SQL to Spark SQL required relatively minor syntax adjustments. The core business logic remained intact, and most transformations translated directly with minimal refactoring.
  4. Optimize for the engine: Porting SQL queries to Spark without optimization produced initially poor results for some workloads. Understanding Spark’s distributed execution model and optimizing for it was critical for achieving target performance.
  5. Validate rigorously: Multi-dimensional data-parity checks (row counts, distinct users, metrics, daily trends, and row-level spot checks) gave the team confidence to cut over without data-quality regressions.
  6. Moving between EMR options is straightforward: EMR Serverless proved very efficient for starting fast and evaluating Spark. When Moovit needed to move to EMR on EC2 to use existing reservations, the transition required no application code changes.
  7. Iterative cluster rightsizing: Rather than a single resize, Moovit reduced the Redshift cluster incrementally (two nodes at a time) using elastic resize, validating performance at each step before proceeding further.

Conclusion

Looking ahead, as another potential optimization, Moovit will be evaluating the new Amazon Redshift RG instances for provisioned clusters, providing up to 2.2x better price performance and priced 30% lower than RA3, powered by AWS Graviton.

The broader takeaway is that AWS provides multiple purpose-built engines that can be used in a single data platform. In Moovit’s case, the biggest improvement came from assigning each workload to the engine that fit it best: Amazon Redshift for curated analytical serving, Redshift Serverless for isolated exploratory workloads, and Amazon EMR for large-scale transformations over data in Amazon S3. This architecture gives Moovit a foundation for future optimization and flexibility as data volumes grow and new analytical use cases emerge.

 


About the authors

Saar Porat

Saar Porat

Saar is the Director of BI & Data Engineering at Moovit, where he has spent more than a decade building and scaling the company’s data engineering capabilities. With nearly 20 years of experience in BI, analytics, and data platforms, he focuses on designing reliable, maintainable, and cost-efficient systems that translate complex data into meaningful business impact. Saar led Moovit’s initiative to migrate major workloads from Amazon Redshift to Apache Spark, improving scalability, performance, and infrastructure efficiency while expanding the team’s engineering capabilities beyond SQL-based processing.

Vova Nevski

Vova Nevski

Vova is a Senior Analytics Specialist Solutions Architect at AWS with more than 15 years of experience in the big data and analytics domain, including data lakes, batch and stream processing, both on premises and in the cloud. He partners with AWS customers to design and build solutions best suited to their unique needs.