My Rambling Thoughts

Stats from GHS '25

DoS (Department of Statistics) just released the General Household Survey 2025 report. It immediately caused a hooha in local forums when ST reported "about 1 in 7 S'pore families earn at least $30k a month". There was widespread disbelief.

How could there be so many, so high?

Many posters on HWZ's EDMW also expressed their shock. This is ironic given that they often used $20k/month pay as a benchmark.

One common explanation is that there is no real increase. Households now have more contributors because adult children stay with their parents due to high house prices.

Some say those who are in disbelief have been left behind... :sweat:

First, let's look at the Monthly Household Market Income table:

|Year|< 3k|< 6k|< 9k|< 12k|< 15k|< 20k|< 25k|< 30k|< 35k|35k+|
|---|---|---|---|---|---|---|---|---|---|---|
|2020|19.7%|15.6%|14.3%|12.3%|9.5%|11.0%|6.4%|3.8%|2.4%|5.0%|
|2025|14.6%|12.2%|10.9%|10.7%|10.0%|12.9%|9.1%|6.2%|4.4%|9.0%|
|2020 cum|0.0%|19.7%|35.3%|49.6%|61.9%|71.4%|82.4%|88.8%|92.6%|95.0%|
|2025 cum|0.0%|14.6%|26.8%|37.7%|48.4%|58.4%|71.3%|80.4%|86.6%|91.0%|

This is the first time income above $20k is broken down. In 2020, we only knew 17.6% earn above $20k. Even then, $20k was too low a bar. It is now raised to $35k — and almost 10% are above it.

$20k used to be 70th to 80th percentile (upper middle-income). It is now only 60th to 70th percentile (slightly above middle income).

Related stats:

||2020|2025|
|---|---|---|
|Avg|$12,396|$16,159|
|Avg per member|$4,111|$5,579|
|Avg employment income|$3,494|$4,439|
|Median|$9,099|$12,446|
|Median per member|$2,952|$4,160|

The average income has gone up significantly and 80% of income is from employment.

The average household size according to the above table is 2.90 (avg) and 2.99 (median). I don't know why they are different, or why they are different from the average household size (3.1).

Market income includes employer CPF, 1/12 of annual bonus and non-employment income, e.g. investments, rental, CPF payout. Some people say this is why the figures are on the high side.

For a single-income at $30k, the employer CPF contribution is only an extra $1.36k. For dual-income at $15k each (anything above $8k, actually), the employer CPF contribution is $2.72k.

If we assume a conservative 2-months bonus, it is $3.33k at $20k. (Using estimated employment income.)

Let's assume a more conservative non-employment income of 15% — $4.5k from a mix of investments and rental.

After adjusting all the factors, we get a figure of ~$21k monthly pay for $30k market income.

Individual income

GHS does not cover individual income, but DOS has an annual Gross Monthly Income From Employment report.
|Year|Total|1.5k+|2k+|3k+|6k+|9k+|12k+|15k+|20k+|22.5k+|
|---|---|---|---|---|---|---|---|---|
|2020|1,945.8k|9.7%|17.5%|34.1%|70.1%|84.2%|91.4%|94.3%|96.9%|97.8%|
|2024|2,067.2k|3.6%|9.4%|23.8%|61.3%|78.4%|88.1%|91.9%|95.6%|96.7%|
|2025|2,100.4k|2.1%|9.1%|22.0%|59.2%|77.1%|87.2%|91.3%|95.3%|96.6%|

It includes 1/12 of annual bonus, but excludes employer CPF. It tops out at $22.5k — top 10% of EP holders. Candidates earning over this are exempted from standard EP point system.

In this table, if you earn between $20k and $22.5k, you are in the 95th to 97th percentile.

From 2020 to 2022, it's like lower-paying jobs just... disappeared.

There is another source of info: Taxable Individuals by Assessed Income Group from IRAS. It has only up to 2024, and it goes by tax residents. Data for 2024:

||> 0|> 20k|> 25k|> 30k|> 40k|> 50k|> 60k|> 80k|> 100k|> 150k|> 200k|> 300k|> 400k|> 500k|> 1mil|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|Number|74.9k|69.4k|125.7k|362.0k|295.0k|222.2k|169.6k|139.8k|213.1k|313.5k|150.9k|128.0k|50.9k|30.3k|9.2k|
|Avg pay|$0|$1.8k|$2.1k|$2.7k|$3.4k|$4.2k|$5.8k|$6.9k|$9.4k|$13.2k|$18.6k|$26.4k|$34.2k|$50.8k|$156.8k|
|%-tile|0.0%|3.2%|6.1%|11.4%|26.6%|39.0%|55.4%|61.3%|70.3%|83.4%|89.8%|95.2%|97.3%|98.3%|99.6%|

How to read the table: if your assessable income is $200k - $300k (avg monthly pay of $18.6k to $26.4k), you are in the 90th to 95th percentile.

There is no figure for non-tax paying residents. I took the number of residents who earned less than $1.5k in 2024 — 74.9k. It is not accurate because 'residents' is not the same as 'tax residents', but it is much better than 0. This allows us to get income percentile for total employed population.

Avg pay is total assessable income divided by the number of people in that band divided by 13 (w/ AWS).

I blame high COE on easy loan and commerical use. I'm not so sure anymore after looking at this table. There are just too many high earners. There are more people earning $150k to $200k (313.5k) except for the $30k to $40k band (362.0k).

These people can own a car comfortably — car price should not exceed annual pay, remember?

Household size

||2020|2025|
|---|---|---|
|1 person|16.0%|16.7%|
|2 persons|22.6%|23.8%|
|3 persons|20.4%|22.6%|
|4 persons|20.1%|19.9%|
|5 persons|11.9%|10.9%|
|6+|9.0%|6.1%|
|Avg size|3.2|3.1|

To get average size of 3.2 in 2020, the 6+ avg is 6.x. In 2025, the 6+ avg size is 7.x.

The way I interpret this is, there are fewer 6-member households, leaving behind 7-members and above.

By living arrangement:

||2020|2025|
|---|---|---|
|Married w/ children|50.4%|47.6%|
|Married w/o children|16.8%|19.1%|
|Lone parent|9.3%|6.8%|
|One person|16.0%|16.7%|
|Others|7.5%|9.8%|

'Others' here can mean: grandparents w/ grandchildren, siblings-only, mixed relatives (e.g. uncle w/ nephew), divorced person living with widowed parent, elderly living only with domestic worker, unrelated roommates. The category is very broad!

The definition of lone-parent is very specific and may not be what you think. The household must:

  • have no married couple
  • at least one never-married / widowed / divorced / separated person
  • living with his/her child(ren), who must be below 16 y.o. or not married

This table is not very useful, it is more useful when broken down by age group.

||Total|< 35|< 50|< 65|65+|
|---|---|---|---|---|---|
|Married w/ children|47.6%|34.0%|56.7%|55.2%|31.6%|
|Married w/o children|19.1%|27.4%|14.8%|12.5%|29.8%|
|Lone parent|6.8%|6.4%|5.3%|9.8%|5.0%|
|One person|16.7%|18.2%|14.5%|13.9%|22.3%|
|Others|9.8%|14.0%|8.7%|8.7%|11.3%|

For 2020:

||Total|< 35|< 50|< 65|65+|
|---|---|---|---|---|---|
|Married w/ children|50.4%|39.0%|60.3%|56.4%|30.2%|
|Married w/o children|16.8%|25.0%|11.3%|11.4%|30.6%|
|Lone parent|9.3%|6.5%|8.6%|11.9%|7.4%|
|One person|16.0%|19.2%|14.2%|13.6%|21.6%|
|Others|7.5%|10.3%|5.7%|6.8%|10.2%|

Can we tell if households now have extra contributors? Not directly, but indirect evidence says no. If only there is a number of contributors per household figure...

Mode of transport to work

||2020|Median time|2025|Median time|
|---|---|---|---|---|
|Public transport|57.7%|50 mins|60.1%|60 mins|
|Taxi/PHV|3.1%|30 mins|2.5%|30 mins|
|Car|21.1%|30 mins|21.2%|30 mins|
|Motorcycle|3.4%|30 mins|2.9%|30 mins|
|No transport|9.8%|8 mins|9.7%|5 mins|

(Does not add up to 100% cos I omitted a few categories.)

I find surprising is that only 60.1% of the people take public transport to work. A full 20% drive! Wow, that's a lot.

There is breakdown by type of property, which I think is more revealing.

||1 - 2-rm|3-rm|4-rm|5-rm n Ex|Condo n Apart|Landed|Others|
|---|---|---|---|---|---|---|---|
|Public transport|70.2%|69.9%|65.1%|59.5%|48.9%|32.6%|46.5%|
|Taxi/PHV|1.6%|2.1%|2.2%|2.1%|4.1%|3.0%|4.2%|
|Car|4.6%|7.8%|14.8%|23.2%|36.6%|51.4%|14.4%|
|Motorcycle|3.5%|3.5%|4.1%|2.9%|0.7%|0.4%|0.0%|
|No transport|14.9%|12.2%|9.7%|8.6%|8.1%|11.1%|31.4%|

'Others' is where the surveyed person stays with someone else without charge.

This must be used together with the following table:

||1 - 2-rm|3-rm|4-rm|5-rm n Ex|Condo n Apart|Landed|Others|
|---|---|---|---|---|---|---|---|
|%-age|7.3%|16.6%|31.2%|22.1%|17.9%|4.7%|0.2%|
|Household size|1.9|2.4|3.2|3.5|3.1|4.1|--|

51.4% of Landed residents drive, but they are only 4.7% of the total population.

For travelling time, median is not enough. We need at least 20th and 90th percentile. We also need breakdown by area.

More logic puzzles


Murdle Book 2 [2023]

I regret getting Book 2. One book is enough.

Mine is a South Asia edition. I bought it for S$24.37. Really got ripped off.


Murdoku Vol 2 [2026]

OTOH, I don't mind Murdoku Vol 2 cos it is easier and in color. I'm shallow! :-P

This is hot off the press!

There are 5 chapters, each themed around a historical setting, with theme-specific rules to add variety. Each chapter has 16 puzzles, except one with 14; they range from easy to expert. There are two more puzzles at the end to round up to 80.

Due to this format, the difficulty ramps up very fast. Only the first two puzzles are easy, followed by medium, then hard, and the last two are expert — there are ten expert level puzzles altogether.

What-if 80286 in an alternate world

Following our alt-8086, let's extend it to 80286. What will 80286 be like if it did not have segmentation?

This is very ironic, because 80286 is the quintessential 16-bit segmented processor. Its memory management is based on segmentation in Protected Mode. It would have worked very well if segments were not limited to 16-bit — 80286 uses 24-bit address, it should allow 24-bit segments.

The answer to our question is simple. Our alt-80286 will use paging for memory management in Protected Mode — brought forward by one generation.

If we use 16 kB pages, the virtual address will look like this:

|Bits|#bits|Purpose|
|---|---|+--|
|14 - 23|10|Page Table|
|0 - 13|14|Offset|

We only need 10 bits for the Page Table, so a Page Table entry can be just 16 bits (6 bits for flags), but it is a little tight — we need 10 bits for flags, ideally — so let's use 32 bits, and we can use the same format when we move to 32-bit.

We only need 1,024 entries, so there is only one Page Table.

If we use all 4,096 entries, we can support an address space of 64 MB — needs 26-bit address bus.

That's it, we are done.

Protected Mode

For our alt-286, Real mode means paging is off. Protected mode means paging is on.

The CPU starts in Supervisor mode with paging off. The OS may set up page tables and enable paging, entering Protected mode. It then enters User mode using IRET.

Interrupts

An interrupt has its own stack, page table and PCID, different from the kernel. ISRs are not fully trusted code!

Interrupt Vector entry:

|Ofs|#bytes|Purpose|
|---|---|+--|
|0|2|Flags|
|2|2|PCID|
|4|4|Page Table addr|
|8|4|Stack addr|
|12|4|Call Stack addr|
|16|4|Entry point|

Flags:

  • Save registers? This is for convenience
  • Run in supervisor mode?
  • Disable interrupt?

Each Interrupt Vector is 20 bytes. Let's make it 32 bytes for future expansion.

An interrupt will always use its Page Table and stack. It will never use the process's stack.

The process's context is saved in its Context memory. This includes the return address.

The process's context address and SP are pushed to the ISR stack. User-mode SP is intended for a system call to access its parameters that are pushed on the process's stack. An ISR won't be able to use it — its Page Table will not have user memory.

Interrupt handling in x86 Protected Mode is notoriously slow. We want interrupts to be fast. I don't know if I count correctly, but we should be able to do it in < 30 clock cycles.

System calls

A system call is made using software interrupt instruction. There is no call gate, jump gate or task gate. There is no TSS (Task State Segment).

There is no need to use a dedicated SYSCALL instruction as interrupts have very little overhead compared to INT on x86.

System calls use kernel page table and stack — by definition.

Optimizing save/restore

Let's say alt-80286 has alt-80287 integrated. This means an additional 8 48-bit registers to save — a total of 48 bytes, or 24 cycles.

It is tempting to save and restore them lazily, as Intel did. FP instructions are trapped in user mode. When they are used, the OS then saves the values for the previous process and restores the values for the current process.

But this leads to LazyFP attack which uses speculative read to avoid tripping the trap. The data can then be teased out of the registers by using cache side-channel read.

A solution is to trap even for speculative read.

An alternative solution is to assign a dirty bit to each optional register. It is cleared if the register is zero. All registers are saved and restored on inter-process context switch, but clean ones are skipped, saving cycles:

  • Save current process: write dirty flags, write dirty registers, skip clean ones
  • Restore new process: read dirty flags, read dirty registers, clean ones are zeroed out

Moral of the story: always zero out registers after use!

Murdle for Juniors


Murdle Jr (Book 1) [2024]

Junior edition, easier for kids below 13 years old to solve. Has 40 puzzles.

It is divided into 5 sections. Each section has 8 puzzles. For the first four sections, there are two 3x3 (2 variables), two 4x4, two 3x3x3 (3 variables) and two 4x4x4 puzzles. The last section has four 4x4 (2 variables), one 3x3x3 (3 variables), one 4x4x4 and two 3x3x3 (4 variables). The last four puzzles are adult standard.


Murdle Jr: Sleuths on the Loose [2025]

This is a mystery novel. Don't buy this book if you are looking for puzzles.

It has only one 4x4x4 logic puzzle (3 variables) that is filled up gradually as the story progresses. You are given a chance to solve the puzzle at the end of the book before the reveal.

It has a bonus 3x3 puzzle (2 variables) at the end.

I knew it was a storybook, but I thought it had puzzles sprinkled throughout. I was mistaken.

I noticed my copy is for South Asia region and is not meant for export. Its MSRP is 499 Indian Rupee, which is S$6.82! I bought it for S$15.46. Its MSRP in UK is 7.99 pounds, or S$13.65.

(I checked Amazon India and it sells for 342 Ruppee, or S$4.68, there. Too bad they don't deliver to Singapore — I estimate shipping to be around S$5.)

It turns out my Murdle Book 1 is also a South Asia edition, 599 Indian Rupee (S$8.19). I bought it for S$20.38. I feel cheated. :lol: Its MSRP in UK is 14.99 pounds, or S$25.62.

It is not surprising that the same book sells much cheaper in South Asia — 1/3 to 1/2 UK MSRP. But the publisher should have at least make it harder to grey import by using a different book cover.

Why is Meta hell now?

One word, Z is desperate.

His AI is way behind.

Previously, he bet on VR. VR is nice, but it is flawed until someone invents a way to move in-place. Not just walking, but running, jumping and other movements. Not even Apple could make VR a thing, just saying.

AI was being worked on, no doubt, but apparently the R&D gamed the metrics too much. It was fine and dandy when everyone just demo'ed bits and pieces — they could get the same results by cherry-picking — but when OpenAI released ChatGPT to the public, the gap was striking. One could carry out a conversation. The other was a toy.

It was not just behind. It was flawed. So much so that they had to abandon it and start from scratch. That's how bad it was. Open source? Forget it, Z has no time for it.

Funnily enough, in the time since, Anthropic has overtaken OpenAI with its Claude LLM. ChatGPT is better with general knowledge, but Claude is better at reasoning and doing things.

Meta is also working on smart glasses. I imagine it will take off in the next few years. By then, it'll be quaint to be using mobile phones.