Page MenuHomePhabricator

mobileapps is comparatively slower to handle changeprop events
Closed, ResolvedPublic

Assigned To
Authored By
hnowlan
Jun 24 2025, 5:08 PM
Referenced Files
F65779161: image.png
Aug 18 2025, 4:18 PM
F62578465: image.png
Jun 27 2025, 9:13 AM
F62447498: image.png
Jun 24 2025, 5:08 PM
F62447482: image.png
Jun 24 2025, 5:08 PM
F62447464: image.png
Jun 24 2025, 5:08 PM
F62447454: image.png
Jun 24 2025, 5:08 PM
F62447447: image.png
Jun 24 2025, 5:08 PM

Description

Compared to equivalent/similar pre-PCS functions, mobileapps is significantly slower than the previous functionality in restbase, which in turn is exacerbating backlogs (T397072) - this can be seen by comparing historical execution times. It's not clear if this limitation is a result of extra complexity in the mobileapps service or if it is a resourcing problem - at the moment it seems like both.

image.png (2,104×811 px, 177 KB)

image.png (2,075×721 px, 288 KB)

Attempts have been made to increase resource allocation to the service, which leads to a paradoxical effect wherein latency skyrockets. Keeping memory limits at 1GB leads to frequent OOMKills at the Kubernetes level, which is not ideal, but allowing workers to consume more memory (even if they do not hit the memory limit or hit it less frequently) leads to requests taking significantly longer and either timing out, or just tying up workers.

Here we can see latency spiking after a resource bump of an increased limit of 2.7GB and recovering after a revert to the 1GB limit

image.png (2,109×725 px, 180 KB)

Paradoxically we can see an overall significant improvement in the (admittedly less busy) codfw cluster with the same bump and no revert:

image.png (2,109×725 px, 181 KB)

Notably also is the drop in error rate in codfw:
image.png (2,113×1,222 px, 241 KB)

Details

Related Changes in Gerrit:
SubjectAuthorRepoBranchLines +/-
Jgiannelosoperations/deployment-chartsmaster+2 -10
Jgiannelosmediawiki/services/mobileappsmaster+35 -15
Hnowlanoperations/deployment-chartsmaster+5 -1
Jgiannelosoperations/deployment-chartsmaster+9 -1
Jgiannelosmediawiki/services/mobileappsmaster+6 -3
Hnowlanoperations/deployment-chartsmaster+6 -1
Hnowlanoperations/deployment-chartsmaster+3 -3
Jgiannelosoperations/deployment-chartsmaster+2 -1
Jgiannelosoperations/deployment-chartsmaster+4 -6
Jgiannelosmediawiki/services/mobileappsmaster+23 -0
Hnowlanoperations/deployment-chartsmaster+3 -3
Hnowlanoperations/deployment-chartsmaster+1 -21
Jgiannelosoperations/deployment-chartsmaster+2 -1
Hnowlanoperations/deployment-chartsmaster+18 -0
Hnowlanoperations/deployment-chartsmaster+3 -0
Hnowlanoperations/deployment-chartsmaster+3 -9
Hnowlanoperations/deployment-chartsmaster+12 -2
Hnowlanoperations/deployment-chartsmaster+5 -1
Hnowlanoperations/deployment-chartsmaster+1 -1
Show related patches Customize query in gerrit

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Change #1163429 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: bump memory limits without scaling down

https://gerrit.wikimedia.org/r/1163429

Change #1163429 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: bump memory limits without scaling down

https://gerrit.wikimedia.org/r/1163429

Change #1163702 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: remove memory limit for canary release

https://gerrit.wikimedia.org/r/1163702

Change #1163702 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: remove memory limit for canary release

https://gerrit.wikimedia.org/r/1163702

Change #1163743 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: add num_worker param, default setting to 0

https://gerrit.wikimedia.org/r/1163743

Change #1163743 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: add num_worker param, default setting to 0

https://gerrit.wikimedia.org/r/1163743

Removing CPU and memory limits results in similar behaviour. mobileapps will eventually peg itself at just over 1*num_workers CPUs and once it hits this point latencies will skyrocket and healthchecks will time out. Before hitting this point it operates normally but after 20 minutes the situation usually becomes chronic. Currently we're running with the old default of num_workers of 2, but we should move this to 0 (no workers and no supervisory thread) in order to get clear expectations of usage and also match our other service-runner/nodejs applications in k8s.

This doesn't seem like something caused by how we're deploying the application in k8s, but something more fundamental to the service codebase where it is getting stuck in a loop or being DoSed by an expensive request.

Change #1163772 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: set num_workers to 0, triple replicas in prod

https://gerrit.wikimedia.org/r/1163772

Change #1163772 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: set num_workers to 0, triple replicas in prod

https://gerrit.wikimedia.org/r/1163772

Change #1163828 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: use guaranteed QoS resource allocation

https://gerrit.wikimedia.org/r/1163828

Change #1163828 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: use guaranteed QoS resource allocation

https://gerrit.wikimedia.org/r/1163828

Change #1164137 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: set requests == limits for other containers

https://gerrit.wikimedia.org/r/1164137

Change #1164137 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: set requests == limits for other containers

https://gerrit.wikimedia.org/r/1164137

Change #1164154 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[operations/deployment-charts@master] changeprop: Debug if-unmodified-since impact on PCS

https://gerrit.wikimedia.org/r/1164154

Change #1164180 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: remove CPU limits in prod

https://gerrit.wikimedia.org/r/1164180

Change #1164154 merged by jenkins-bot:

[operations/deployment-charts@master] changeprop: Debug if-unmodified-since impact on PCS

https://gerrit.wikimedia.org/r/1164154

Change #1164180 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: remove CPU limits in prod

https://gerrit.wikimedia.org/r/1164180

Change #1164227 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: revert to original worker count, restore CPU limits

https://gerrit.wikimedia.org/r/1164227

Change #1164227 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: revert to original worker count, restore CPU limits

https://gerrit.wikimedia.org/r/1164227

hnowlan triaged this task as High priority.Jun 26 2025, 3:03 PM

A few notes:

Throttling is happening even when mobileapps is not hitting the CPU limits. This isn't uncommon in Kubernetes, but some node services like changeprop have shown themselves to be more sensitive to throttling than other services. There appears to be a link between latency increases and bursts of throttling, but removing CPU limits entirely for all production pods didn't produce an appreciable improvement in the latency and error rates we have been seeing. In general a few days of experimentation indicate that resource limits are not making the situation better, but they are not the cause.

All experiments so far indicate that when a mobileapps instance pegs itself at num_workers CPU usage, latencies increase, healthchecks fail and errors increase. There are no resource or worker configurations that change this fact, and all signs point to an issue with the mobileapps codebase where there are some runaway resource management or garbage collection issues, or a loop that is never broken out of.

We do not have garbage collection statistics available for mobileapps so our investigation is limited. We attempt to capture these metrics for multiple service-runner services despite the fact that we have not gathered these statistics in service-runner since 2021. Having these stats would be very useful for investigating this situation.

num_workers was set to 2 for mobileapps. To conclude the experimentation this will be reverted, but in general is very much something we try to avoid in kubernetes as all other service-runner services are run with a value to 0 to ensure predictable resource usage and avoiding the use of unnecessary extra threads.

The various changes to latency have created a bit of noise for wikifeeds (T397937).

Given the effort that has been spent arriving to this point, the only option is to restore the initial known-but-broken settings and hope that the service can be investigated.

Here we can see execution times in changeprop getting significantly worse from 1500 onwards after reverting to the original pod configuration

image.png (2,076×919 px, 166 KB)

In a VM i tried spinning of mobileapps and profile it with some traffic from changeprop events.
I didn't manage to reproduce this behaviour. I think ideally we could try enabling profiling with the same dataset I built to see if the behaviour is reproduced there.

Change #1165068 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[operations/deployment-charts@master] mobileapps: Use profiler script to spawn profiler

https://gerrit.wikimedia.org/r/1165068

Change #1165037 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[mediawiki/services/mobileapps@master] debug: Add node profiler script

https://gerrit.wikimedia.org/r/1165037

Change #1165037 merged by jenkins-bot:

[mediawiki/services/mobileapps@master] debug: Add node profiler script

https://gerrit.wikimedia.org/r/1165037

Change #1165068 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: Use profiler script to spawn profiler

https://gerrit.wikimedia.org/r/1165068

Change #1165469 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[operations/deployment-charts@master] mobileapps: Fix command/args definition for staging debugging

https://gerrit.wikimedia.org/r/1165469

Change #1165469 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: Fix command/args definition for staging debugging

https://gerrit.wikimedia.org/r/1165469

Change #1165483 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mw-api-int: bump replicas

https://gerrit.wikimedia.org/r/1165483

Change #1165483 merged by jenkins-bot:

[operations/deployment-charts@master] mw-api-int: bump replicas

https://gerrit.wikimedia.org/r/1165483

Change #1165838 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] mobileapps: allow setting terminationGracePeriodSeconds

https://gerrit.wikimedia.org/r/1165838

Change #1165838 merged by jenkins-bot:

[operations/deployment-charts@master] mobileapps: allow setting terminationGracePeriodSeconds

https://gerrit.wikimedia.org/r/1165838

Change #1166851 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[mediawiki/services/mobileapps@master] pregeneration: Return 412 for stale events

https://gerrit.wikimedia.org/r/1166851

Change #1166851 merged by jenkins-bot:

[mediawiki/services/mobileapps@master] pregeneration: Return 412 for stale events

https://gerrit.wikimedia.org/r/1166851

Change #1167249 had a related patch set uploaded (by Hnowlan; author: Hnowlan):

[operations/deployment-charts@master] changeprop: don't process File: pages for mobile html pages in PCS

https://gerrit.wikimedia.org/r/1167249

Change #1167524 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[operations/deployment-charts@master] pcs: Use purge only requests for mobile-html transcludes

https://gerrit.wikimedia.org/r/1167524

Change #1167524 merged by jenkins-bot:

[operations/deployment-charts@master] pcs: Use purge only requests for mobile-html transcludes

https://gerrit.wikimedia.org/r/1167524

Change #1167249 merged by jenkins-bot:

[operations/deployment-charts@master] changeprop: don't process File: pages for mobile html pages in PCS

https://gerrit.wikimedia.org/r/1167249

Change #1167657 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[mediawiki/services/mobileapps@master] Move purgePath definition before caching middleware

https://gerrit.wikimedia.org/r/1167657

Change #1167657 merged by jenkins-bot:

[mediawiki/services/mobileapps@master] Move purgePath definition before caching middleware

https://gerrit.wikimedia.org/r/1167657

I did some analysis on the backlog:

From a sample of 10M events backlogged:
Here are the top 10 prefixes of articles by frequency:

{'File': 5782542,
 None: 2560547,
 'Discussion': 691871,
 'Talk': 207053,
 'Template': 140321,
 'User_talk': 135208,
 'User': 92992,
 'Kategori': 49359,
 'Category': 35529,
 'Wikipedia': 31320}

And the top 10 domains:

{'commons.wikimedia.org': 5861939,
 'fr.wikipedia.org': 1079475,
 'en.wikipedia.org': 542725,
 'uk.wikipedia.org': 432521,
 'zh.wikipedia.org': 359482,
 'sv.wikipedia.org': 356877,
 'ig.wikipedia.org': 264469,
 'fi.wikipedia.org': 192952,
 'de.wikipedia.org': 108362,
 'pl.wikipedia.org': 97321}

Change #1167834 had a related patch set uploaded (by Jgiannelos; author: Jgiannelos):

[operations/deployment-charts@master] changeprop: Simplify pcs rules, use purge instead of pregen

https://gerrit.wikimedia.org/r/1167834

Change #1167834 merged by jenkins-bot:

[operations/deployment-charts@master] changeprop: Simplify pcs rules, use purge instead of pregen

https://gerrit.wikimedia.org/r/1167834

Jgiannelos claimed this task.

fwiw I think that many of the performance issues here are still unresolved. I'm happy to resolve this issue for now, but if we encounter issues in another way in future this ticket will be good for reference

From what I understand from the execution times diagram it looks like the numbers have dropped significantly:
https://grafana.wikimedia.org/goto/66HPykXHg?orgId=1

image.png (3,422×1,840 px, 589 KB)

Is there any specific performance issue you can point out so we can plan to tackle?
I think that with cache purging instead of pregeneration of content on each changeprop request we should be even faster than before when it comes to changeprop traffic, since for each incoming req we only do a cassandra delete instead of invoking a chain of requests to MW.

I assume the main concern is the behaviour identified in https://phabricator.wikimedia.org/T397750#10950977

Given that:

  • we don't have enough data to identify the root cause
  • and we can't reproduce it in an environment that is very close to prod (k8s with proxying like service mesh using the same images and the same service config)

there is not much we can do with the current setup

If we want to improve the specific performance concern other than the steps already taken we need to have some sort of observability on the path cassandra/PCS/service mesh/MW and a way to trigger the issue in prod.