case study
We didn't have a traffic problem. We had a systems problem.
When I joined Sheypoor, traffic had been declining for roughly eight months and nobody could say exactly why. This is the story of what we found underneath — and of the organisational work that turned out to be inseparable from the technical work.
- Role
- VP of Engineering, reporting to the CEO
- Organisation
- Roughly 65 engineers, seven teams
- Stack
- PHP · Python · Golang
Some figures are approximate or expressed as ranges to preserve confidentiality.
Context
Sheypoor is one of Iran's largest classifieds platforms, serving more than five million monthly users. The engineering organisation was around 65 people, structured into Core, Monetization, DevOps, Infrastructure, QA, Mobile, and Frontend. Each team had a lead; the leads reported to me; I reported to the CEO. There was no separate CTO — the role I stepped into carried both the technical and the organisational responsibility.
The business was not in a strong position when I arrived. A significant traffic decline had started roughly eight months earlier and was still happening. The root cause was unclear — and that uncertainty shaped everything that followed.
Two critical problems
The first problem was visible in every business review: acquisition was sliding, and with it the top of the funnel for the whole company.
The second was quieter but, in retrospect, just as serious. The Android application had gone roughly two years without a production release. Development and refactoring work had continued the whole time — but that work had never turned into a reliable release cycle. The organisation could build, but it could not ship.
What we knew — and what we didn't
It would be tidy to say we had a hypothesis. We didn't. What we had was a set of instruments and a lot of open questions.
- We knew traffic was declining and had been for roughly eight months.
- We didn't know whether the cause was primarily SEO, product experience, technical performance, or some combination.
- We knew the Android app had not shipped to production in about two years.
- We didn't know how much that was a mobile engineering problem and how much it was an organisational one.
That distinction — between what the data said and what it meant — took most of the work.
Investigation
We investigated across three sources: Google Search Console, application logs, and ranking data. None of them alone told the story; together, patterns started to appear.
What made this slow — and worth doing carefully — is that the trail crossed every team boundary: search visibility, web performance, mobile, backend services. A problem that shows up as "traffic" in a board deck rarely lives in one team's codebase.
Root causes
The investigation eventually pointed to several distinct problems:
- SEO problems, tied significantly to the frontend's server-side rendering.
- Deep-link problems that broke the path from notification or web into the app.
- Push notification problems that needed a new Android release to fix.
- A frontend rewrite — a custom SSR framework — that had been under development for more than a year without resolving the underlying issues.
- The Android application's inability to release reliably.
Individually, each looked like a discrete technical issue. Together they described a system that had accumulated debt faster than it had accumulated the ability to pay it down.
The SSR decision
Stop investing in our custom SSR framework. Rewrite the affected SSR pages with Next.js.
Why: the framework had consumed more than a year of effort and was still contributing significantly to the SEO problem. Our competitive advantage was not building rendering infrastructure — it was the product. The ecosystem already solves this problem better than we ever would.
The principle behind the decision matters more than the technology choice: we are not in the business of building an SSR framework. Our job is to create value for customers, not to reinvent infrastructure that a mature open-source ecosystem can provide. Engineering ownership is valuable when it creates differentiation; owning infrastructure for its own sake becomes a distraction from the product.
The rewrite was a team effort across Frontend and Core. Roughly 20+ days after the new frontend launched, Core Web Vitals were passing across the board. Conversion improved, and the SEO issues that had been bleeding acquisition were addressed.
Deep links: a conversion problem in backend clothing
Deep-link issues were another contributor to the conversion problem — users arriving from links were not landing where they should. These were resolved through changes to backend services.
The Android release: regaining the ability to ship
Fixing push notifications required a new Android release — which collided with an awkward fact: the app had not had a production release in roughly two years. Work had continued on it constantly, but somehow never converged into a releasable state.
Shipping that release became one of the hardest and most valuable things the engineering team did during my time there. It was a team achievement — my role was to make it the priority, clear the path, and keep the organisation patient while the mobile team did difficult work.
The important outcome was not "we released a new version". It was that the organisation regained the ability to ship. After that release, the cycle was corrected: the app moved to roughly monthly releases, and teams could release independently and regularly.
In retrospect, I see the two-year gap as more than a mobile engineering problem. A team that cannot release is rarely facing only a deployment problem — it is facing an organisational capability problem, expressed through deployment.
The organisational changes
Alongside the technical decisions, the organisation itself changed:
- Team structure changes, so ownership matched the problems we needed solved.
- Hiring new people, and replacing people where necessary to address current problems.
- Clearer ownership across systems and product areas.
- More active participation from teams in technical roadmaps and engineering improvements.
- Independent, regular releases as the norm rather than the exception.
My role in all of this was facilitating and leading the team: helping identify the real problems, helping choose appropriate technology, making architecture decisions with the teams, hiring and replacing where necessary — building an organisation capable of solving its own problems, not an organisation that waits for its leadership to solve them.
Outcomes
When I joined
- Traffic declining for roughly eight months, cause unclear.
- Android app: roughly two years without a production release.
- A custom SSR framework consuming effort without resolving SEO.
- Ownership blurred across team boundaries.
When I left
- Both critical problems resolved.
- Regular, independent releases — roughly monthly.
- Core Web Vitals green across the board; conversion improved.
- Clearer responsibilities and stronger ownership.
Teams participated actively in technical roadmaps, and the system could be improved continuously instead of episodically.
What I would do differently
I would have made the organisational decisions more decisively.
In retrospect, I would have made structural decisions earlier, clarified roles earlier, made the interaction model with stakeholders clearer, and established clearer organisational boundaries sooner. Some technical problems were visible before the organisational structure around them was clear — and I under-estimated how much that ambiguity slowed the technical work itself.
Broader lessons
I've written the transferable versions of these lessons separately: