Mobile
EN

The seven deadly sins in Mobile Team

Seven common pitfalls that mobile teams encounter and how to recognize and fix them. From over-engineering to procrastination, learn how to build healthier team practices.

15 min read
Contents

Mobile development teams face recurring challenges that, while seemingly small in isolation, compound into systemic problems. Here are seven patterns that undermine team effectiveness and how to address them.

1. Pride: Over-engineering and the “I know better” syndrome

“You can not inspect quality into a product.” — Harold F. Dodge

The sin

Pride is the oldest one. In engineering, it rarely shows up as arrogance. It shows up as over-engineering, as building something sophisticated because it looks smart rather than because it is needed. It is the moment we stop listening to users, clients, or teammates because we are already sure we are right.

Every engineer has been there. You architect a beautiful abstraction for a feature that ships once. You turn a simple boolean into a reactive pipeline with three layers of indirection. It feels like craft. It reads like vanity.

Symptoms

  • Building something overly sophisticated, not because it is needed but because it looks smart
  • Quietly tuning out users, clients, or teammates
  • Adding abstractions for futures that never arrive
  • Refusing to ship the “boring” solution

Illustrations

Naming tells the whole story. An interface like WhateverScreenTimeBadgeSetHasSeenUseCase : CompletableUseCase<Boolean> is technically accurate and humanly unreadable. Behind it, a use case that wraps a simple && between two observables.

interface WhateverScreenTimeBadgeSetHasSeenUseCase : CompletableUseCase<Boolean>

class AScreenObserveStatusUseCaseImpl @Inject constructor(
    private val homeRepository: HomeRepository,
    private val whateverObserveAvailabilityUseCase: WhateverObserveAvailabilityUseCase,
) : WhateverScreenTimeBadgeSetHasSeenUseCase {
    override fun execute(params: Unit): Observable<Boolean> =
        Observable.combineLatest(
            whateverObserveAvailabilityUseCase.execute(Unit),
            homeRepository.observeHasSeenBadge(),
        ) { isAvailable, hasSeenBadge ->
            isAvailable && !hasSeenBadge
        }
}

What is quality, really?

The pride trap is that we optimize for our own definition of quality and forget the others exist.

Developers look for code that is easy to read, easy to edit, efficient. Product managers look for something useful, easy to explain, and capable of bringing in money. Users look for something that does the job, is easy to use, and (why not) fun or enjoyable.

A team that over-engineers nails the first definition and misses the other two. A feature can be elegant internally and still fail every test that matters outside the IDE.

How to fix it

Three mental filters. Nothing new, just worth revisiting regularly.

  • KISS (Keep It Simple, Stupid): the simplest solution that works is almost always the right one.
  • YAGNI (You Aren’t Gonna Need It): do not build for hypothetical futures. If you don’t need it today, you probably never will.
  • SOLID: lean on principles, not personal preferences. Your taste is not a specification.

Takeaway

Humility is a technical skill. The code you didn’t write is the code nobody has to maintain.


2. Greed: Wanting everything, right now

The sin

Greed in engineering rarely looks like evil. It looks like ambition. More features, more microservices, more repos, more tickets in flight. Every one of them seems reasonable on its own. Together, they quietly paralyze the team.

Symptoms

  • Adding feature after feature to the backlog with no real sense of priority
  • Stacking projects (more repos, more microservices) without the human or technical capacity to handle them
  • Unclear Definition of Ready and Definition of Done: user stories enter the backlog without anyone ever validating the real acceptance criteria
  • A backlog that keeps overloading with tickets
  • A massive work-in-progress that never really progresses

Why it matters

A team drowning in simultaneous tasks produces less than a team focused on one thing at a time. This is not motivational poster talk. It is how queuing theory works. The more WIP you carry, the longer the lead time for every single item. And the more context switching, the higher the defect rate.

How to fix it, part 1: the Lean toolbox

Six patterns borrowed from Lean manufacturing that map beautifully to software delivery.

  • Sequencer: order the tasks, define a clear launch agenda. Decide what comes first, and why.
  • Suspended: make disturbances and anomalies visible instead of absorbing them silently.
  • Red bin: detect non-compliant parts as defective and prompt rapid problem resolution. Do not let bad items stay in the stream.
  • One Piece Flow: one job at a time. It lets you quickly identify defects and fix them while the context is still fresh.
  • Heijunka: smooth production based on demand. Avoid peaks and troughs in load. Maintain a continuous and stable flow.
  • Pull flow: instead of pushing work down the pipeline based on a forecasted plan (which often leads to overproduction), wait for the next step to pull exactly what it needs, when it needs it.

How to fix it, part 2: prioritize ruthlessly

  • Timeboxing: fixed duration, single task, evaluation right after. If the timebox ends and you are not done, you have information, not a failure.
  • MoSCoW: Must have, Should have, Could have, Won’t have. The “Won’t” is the hardest and the most important.
  • Impact: let data decide. What percentage of users does this affect? What do the analytics say? Do you actually know your users?

Takeaway

Less work in progress equals more work done. Every team rediscovers this the hard way. The goal is to discover it on purpose.


The sin

Every mobile developer knows the pull. A new library drops, a trending talk airs, a shiny framework shows up on your timeline, and suddenly the stack you built last quarter feels outdated. Lust is the constant urge to chase the latest trends, tools, and gadgets.

Symptoms

  • Jumping on every new tech or framework without ever asking “What is the real ROI? Who is going to maintain it?”
  • Living in a state of permanent proof-of-concept, never taking the time to stabilize a reliable foundation or pipeline
  • Rewriting what already works because something new appeared on Reddit
  • A CHANGELOG full of migrations and very few features

Why it matters

Novelty-driven decisions accumulate. Three half-finished migrations are worse than one boring, stable stack. Every unfinished proof-of-concept is a silent lien on future sprints, and the team paying the interest is always the next one.

How to fix it: invest in the foundations

Instead of chasing what is new, double down on what makes your current stack fast, reliable, and pleasant to work with. For a Gradle-based Android project, that means four concrete levers.

1. Gradle Profiler

Stop guessing about build time. Measure it.

$ brew install gradle-profiler
$ gradle-profiler --benchmark assembleDebug

You can define scenarios (clean builds, incremental builds, Android Studio sync) and get reliable comparisons between configurations. Real numbers replace anecdotes, and suddenly the “but it feels slower on my machine” debate ends.

2. Gradle Version Catalog

A single source of truth for every library and plugin version in your project.

[versions]
kotlin = "2.1.0"
coroutines = "1.7.3"

[libraries]
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }

[plugins]
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

Benefits:

  • 🎯 Single source of truth for each library
  • 🔍 IDE auto-completion across modules
  • 🔄 Easier updates with Dependabot or Renovate
  • 🧼 Fewer chances of mistakes

3. Gradle Convention Plugins

Stop copy-pasting the same Gradle code across ten modules. Extract the common configuration into convention plugins.

build-logic/
├── build.gradle.kts
├── settings.gradle.kts
└── convention/
    ├── build.gradle.kts
    └── src/main/kotlin/
        ├── AndroidApplicationConventionPlugin.kt
        ├── AndroidLibraryConventionPlugin.kt
        └── KotlinLibraryConventionPlugin.kt

Benefits:

  • 🔁 Avoid duplicating Gradle code
  • 🔧 Enforce consistent standards across modules
  • ♻️ Easily reuse shared configurations
  • 🧼 Keep each module’s build.gradle.kts clean and readable

4. Gradle Managed Devices

Full automation for UI tests. No need to launch emulators manually, and it plays nicely with CI.

./gradlew pixel4api30aospatdDebugAndroidTest

Benefits:

  • ✅ Full automation for UI tests
  • ✅ No need to launch the emulator manually
  • ✅ Works seamlessly with CI (GitHub Actions, GitLab, etc.)
  • ✅ Easy to configure and integrate into your pipeline

Takeaway

Foundations are boring. Boring foundations are what let you safely be exciting in the product layer.


4. Envy: Comparing yourself to others

The sin

You watch a conference talk. The team on stage claims 40 deploys a day, zero incidents, full trunk-based development with no branches. You go home and feel bad. That is envy.

Envy is comparing yourself to others and ignoring your own context.

Symptoms

  • Trying to copy what the “cool” teams are doing, without really understanding your own context
  • Getting so focused on others’ success that you forget to actually talk to each other
  • Adopting practices because they worked at Spotify, Netflix, or Google, without ever asking what problem they were solving there
  • Retros that turn into “why don’t we do it like company X does?”

Why it matters

Best practices out of context become anti-patterns. A technique that works at a 500-engineer company with dedicated platform teams might destroy a 5-person mobile team with shared ownership. What you see on stage is the highlight reel, filmed after three years of messy iteration nobody talks about.

How to fix it

Get to know each other

Before copying someone else’s setup, look inward. What skills does your team have? What constraints are real? What is the actual bottleneck? These questions are not glamorous, and they are the only ones that matter.

Single Source of Truth

One place for decisions, documentation, metrics, roadmaps. Not five wikis, not scattered Slack threads, not “ask Jean-Michel, he knows.” When everyone points to the same source, debates become shorter and onboarding becomes faster.

Accelerate (DORA metrics)

The research behind the book Accelerate (Forsgren, Humble, Kim) gave the industry four honest, measurable signals of delivery performance. They describe the whole system, not one person’s output, and they let you compare your team only to its past self (the only comparison that really helps).

Velocity

  • Deployment frequency
  • Lead Time (from code commit to production)

Quality

  • Percentage of deployment failures
  • Average time to fix an error (MTTR)

Track these over a few months and you will see your real trajectory, not the imagined one.

Takeaway

Your context is your context. Copy principles, not configurations.


5. Gluttony: Too many processes and meetings

The sin

Monday, 9 a.m. You open your calendar. Fourteen recurring meetings. Three Kanban boards. Two standups, one of which is called “the real standup.” You have not written a line of code yet. That is gluttony.

Gluttony is too many processes and meetings. It feels productive because there is so much motion. There is just very little output.

Symptoms

  • Multiplying meetings, reviews, and boards (Kanban, Slack, Notion, Jira) until everyone is overwhelmed
  • Constant context switching
  • Excessive administrative processes
  • New ceremonies added, existing ceremonies never removed
  • A team that knows the sprint ritual by heart and can no longer say what the sprint is for

Why it matters

Every recurring meeting costs hours of focus across the team. Every process added rarely gets removed. After two years, your team spends more time reporting on work than doing it.

A developer interrupted every 30 minutes does not produce half the work of a developer interrupted every 2 hours. They produce a small fraction of it, because flow state takes 15 to 20 minutes to rebuild after each interruption. Gluttony is quietly the most expensive sin on the list.

How to fix it

Automate

If a task repeats, a machine should do it. CI/CD pipelines, linting, formatting, releases, dependency updates, reports, screenshots, code coverage checks, changelog generation, release notes. The first hour spent automating a process usually pays back within weeks.

Audit the calendar

Once per quarter, list every recurring meeting and ask two questions:

  1. Does this meeting drive a decision?
  2. Would anyone notice if we cancelled it for a month?

If the answer to both is “no,” kill it. No hard feelings.

Default to asynchronous

Most discussions do not need a meeting. A well-written document, a Loom video, a threaded Slack message, a short RFC. Keep meetings for the moments where real-time back-and-forth genuinely matters (alignment on scope, conflict resolution, creative work).

One tool per job

Pick one board, one doc tool, one place for decisions. Duplication is gluttony wearing a productivity sticker.

Takeaway

Process exists to serve the team, not the other way around. When in doubt, remove rather than add.


6. Wrath: When emotions take over

The sin

Merge conflicts are not just a Git problem. They happen between people too. Wrath shows up when we stop solving problems together and start winning arguments instead.

Symptoms

  • Merge conflicts, not just in Git but between people
  • No one is really sure what “done” means, so we argue instead
  • Everyone wants to be right: code reviews turn sharp, Slack threads get spicy, collaboration turns into competition
  • Passive aggression in PR comments, escalation in DMs
  • Whole sprints rewriting each other’s code out of principle

Why it matters

The bigger the pull request, the longer the review takes. It is not linear, it is exponential.

A 50-line PR gets reviewed in minutes. A 1000-line PR creates a week of debate, half of it about things the reviewer did not even understand yet. Size alone generates wrath, and wrath generates more wrath. The cure is to agree on the rules before the review, not during it.

How to fix it: the 5W for code reviews

  • Why? Knowledge sharing (again, and again, and again). The goal is not to police, it is to spread understanding across the team.
  • What? Every PR follows established conventions: scope, naming, description, testing notes.
  • Who? Who ultimately decides if the code is ready for use? Explicit ownership prevents ambiguity.
  • When? Set expectations on turnaround. A PR waiting three days is rotting.
  • Where? Async by default, but open the door to pairing or remote screen sharing when something is worth a real conversation.

Supporting tools

  • Documented Code Review Best Practices
  • A clear PULL_REQUEST_TEMPLATE.md so reviewers know what to look for
  • CI Integration so machines catch lint, tests, and obvious issues before humans argue about them
  • SCA / SAST (Software Composition Analysis, Static Application Security Testing) so security concerns are flagged automatically, not debated in a thread

Beware of interruptions

A classic wrath generator: the Slack “Hi” with no content.

Hi                                                 10:02
                                       Hello      10:03
sup?                                               11:42
                                   I'm fine and you?   11:42
I have a question for you                          14:02
But it's better if we talk about it later.         14:02
When are you available?

Four hours of half-interruption for a question that could fit in one message. See nohello.net for a concise manifesto.

Takeaway

Good engineering culture makes it easy to disagree about code and impossible to attack a person. Set the rules when everyone is calm.


7. Sloth: The quiet comfort of postponing what really matters

The sin

Sloth is the most comfortable of the seven. It does not shout. It waits. It agrees, nods, and quietly moves the hard thing to next sprint. Then the sprint after. Then forever.

Symptoms

  • “We know we should add tests or monitoring, but we will do it later”
  • Pushing decisions to “later,” delaying retros, slowly abandoning continuous improvement
  • Tech debt that grows faster than the team can acknowledge it
  • Runbooks that live in one person’s head

Illustrations

You have heard these sentences. Every team has.

  • “CI’s broken again?”
  • “We’ll fix it in another ticket.”
  • “Preprod’s still down?”
  • “Yeah, just send me the secrets on Slack, don’t bother.”
  • “I have no idea! It’s Jean-Michel who usually does that.”
  • “We keep having the same problem…”

Each one is a tiny concession. Together, they rot the foundation.

Why it matters

Sloth does not cause outages on day one. It causes them on day 400, when three shortcuts intersect with a new person on call, and suddenly nobody remembers how the deployment script actually works.

The cost of sloth is always paid by your future self and by the teammate who joined last week.

How to fix it: the PDCA cycle

Plan, Do, Check, Act. A Deming loop that replaces procrastination with small, consistent motion.

Plan

  • Identify a problem
  • Define an action plan
  • Measure it (you need a baseline)

Do

  • Implement the plan on a small scale, to test its effectiveness before rolling it out everywhere

Check

  • Make adjustments based on what you observed
  • Standardize what worked

Act

  • Evaluate the results achieved against the objectives you set
  • Measure it again (close the loop)

Then restart. The whole point is that the loop never stops turning.

Takeaway

Small motion beats big intention. A team that fixes one thing every week is infinitely more reliable than a team that plans a quarterly overhaul and never ships it.


Final Thoughts

These seven sins are not rare occurrences—they are patterns every mobile team encounters. Recognition is the first step. Once you see them, you can address them systematically. The goal is not perfection, but continuous, intentional improvement.