Skip to content
career_db

← projects/WHERE slug = 'pabau'

row 2 of 4

Clinic & booking platform

Pabau

Booking software for clinics, where the calendar is the product and every user is looking at a different week.

record7 fields
slug
pabau
kind
Clinic & booking platform
year
2022 — 2023
role
Full-stack developer, product team
stack
Next.js, TypeScript, GraphQL, Hasura, Prisma, LESS
repo
NULL
Fig. 01 — schematic
Collapsing a chained request waterfall into a single shaped queryBefore: five requests run one after another, each waiting on the last, before the week view can render. After: one shaped query returns the fields the view draws, with a subscription pushing later changes.BEFORE — FIVE ROUND TRIPS, EACH WAITING ON THE LASTappointmentspractitionersroomspatientsnotesweek view rendersAFTER — ONE SHAPED QUERY, THEN SUBSCRIBEweek viewweek view renderschangespushedSEQUENCE, NOT MILLISECONDS — SCHEMATIC
Five chained requests collapsed into one shaped query, with later changes pushed by subscription rather than fetched on a timer.

Pabau is practice-management software for clinics and salons. I joined the product team as my first professional role and worked on the booking surfaces: the calendar, the appointment flows, and the GraphQL layer feeding them.

01The problem

A clinic calendar is a dense, high-churn view. It holds many practitioners, many rooms, and many appointments at once, and it changes while you are looking at it. Every member of staff opens it to a different week, filtered differently.

The interface felt slow, and the instinct on a React team is to reach for memoisation. That instinct was wrong here. The components were re-rendering because they were being handed new data on every poll, and they were being handed too much of it — a week view was pulling relations it never displayed.

02What I did

I worked backwards from the render to the query. Where the calendar was making several round trips to compose one view, I collapsed them into a single shaped GraphQL query so the component received exactly the fields it drew and nothing more.

For the parts that had to stay current, I leaned on Hasura's subscriptions rather than interval polling, so a changed appointment pushed one small update instead of the client re-fetching a whole week on a timer.

The React work that remained was then genuinely about rendering: stable keys, splitting the week grid so a single-cell change did not invalidate the row, and keeping derived values out of the render path.

03On reflection

I spent my first weeks optimising renders before I had looked at the network tab. I would now read the payload first on any interface that feels slow. It is a faster diagnosis and it is usually the real answer.

next row

MetDaan

Digital media publication

Back to table