Why server-side logic reduces client complexity in Supabase - Performance Analysis
We want to see how moving logic to the server changes how much work the client does.
How does this affect the number of operations the client must perform?
Analyze the time complexity of client vs server logic in Supabase.
// Client fetches all items and filters locally
const { data, error } = await supabase
.from('items')
.select('*')
const filtered = data.filter(item => item.category === 'books')
// Server filters items before sending
const { data: filteredData, error: filteredError } = await supabase
.from('items')
.select('*')
.eq('category', 'books')
The first fetch gets all data and filters on client; the second fetch filters on server.
- Primary operation: Fetching data rows from the database.
- How many times: Once per query, but amount of data fetched varies.
- Client filtering: Happens for every item received.
- Server filtering: Happens once inside the database engine.
As the number of items grows, client filtering work grows with all items fetched.
| Input Size (n) | Approx. Client Filtering Operations |
|---|---|
| 10 | 10 filter checks |
| 100 | 100 filter checks |
| 1000 | 1000 filter checks |
With server filtering, client only processes filtered results, so work stays smaller.
Time Complexity: O(n)
This means client work grows linearly with data size when filtering client-side.
[X] Wrong: "Fetching all data and filtering on client is just as fast as server filtering."
[OK] Correct: Client must handle every item, so work grows with total data size, causing slower response and more data transfer.
Understanding where to place logic helps you design systems that keep clients fast and responsive, a key skill in cloud development.
"What if the server filters data but also paginates results? How would that affect the time complexity on the client?"
Practice
Solution
Step 1: Understand client responsibilities
The client usually handles user interface and simple logic but complex rules can make it bulky.Step 2: Role of server-side logic
Moving complex rules to the server means the client only sends requests and receives results, simplifying its code.Final Answer:
Because the client does not need to handle complex rules or validations. -> Option AQuick Check:
Server logic reduces client complexity = A [OK]
- Thinking client stores all data locally
- Assuming client runs faster without network
- Believing client can change database schema
Solution
Step 1: Check PostgreSQL function syntax
PostgreSQL functions use CREATE FUNCTION, specify RETURNS, and use $$ to wrap the body with LANGUAGE plpgsql.Step 2: Identify correct syntax in options
CREATE FUNCTION check_user() RETURNS void AS $$ BEGIN IF NEW.age < 18 THEN RAISE EXCEPTION 'Too young'; END IF; END; $$ LANGUAGE plpgsql; correctly uses CREATE FUNCTION, RETURNS void, $$ body $$, and LANGUAGE plpgsql.Final Answer:
CREATE FUNCTION check_user() RETURNS void AS $$ BEGIN IF NEW.age < 18 THEN RAISE EXCEPTION 'Too young'; END IF; END; $$ LANGUAGE plpgsql; -> Option AQuick Check:
Correct PostgreSQL function syntax = D [OK]
- Omitting RETURNS keyword
- Missing $$ around function body
- Using THROW or RAISE ERROR instead of RAISE EXCEPTION
CREATE FUNCTION check_age() RETURNS trigger AS $$ BEGIN IF NEW.age < 18 THEN RAISE EXCEPTION 'User too young'; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER age_check BEFORE INSERT ON users FOR EACH ROW EXECUTE FUNCTION check_age();
Solution
Step 1: Understand trigger behavior
The trigger runs BEFORE INSERT and checks if NEW.age is less than 18.Step 2: Analyze condition for age 16
Since 16 < 18, the trigger raises an exception 'User too young', which stops the insert.Final Answer:
The insert fails with an error 'User too young'. -> Option CQuick Check:
Trigger raises error on age < 18 = C [OK]
- Thinking insert succeeds despite error
- Assuming age auto-corrects to 18
- Believing insert is ignored without error
CREATE FUNCTION check_age() RETURNS trigger AS $$ BEGIN IF NEW.age < 18 THEN RETURN NULL; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;
What is the main issue?
Solution
Step 1: Understand RETURN NULL in triggers
In BEFORE INSERT triggers, returning NULL silently skips the row without error.Step 2: Correct way to block insert
To block inserts with an error, the function must RAISE EXCEPTION instead of returning NULL.Final Answer:
The function should use RAISE EXCEPTION to block inserts, not RETURN NULL. -> Option DQuick Check:
Use RAISE EXCEPTION to block inserts = A [OK]
- Returning NULL expecting error
- Forgetting EXECUTE FUNCTION in trigger
- Returning OLD in insert triggers
Solution
Step 1: Enforce email uniqueness
A UNIQUE constraint on the email column ensures no duplicates at the database level.Step 2: Enforce age rule server-side
A BEFORE INSERT trigger function can check age and raise an exception if under 18, blocking invalid inserts.Final Answer:
Use a UNIQUE constraint on email and a BEFORE INSERT trigger function that raises an exception if age < 18. -> Option BQuick Check:
Database constraints + trigger enforce rules, reduce client code = B [OK]
- Relying only on client-side checks
- Using triggers without constraints for uniqueness
- Ignoring age validation on server
Ready to prove it?
Pass the test and this pattern moves unknown
