Toilets and engineers
It started with a lunch conversation that slowly turned into a coffee time mini-debate. You see, I moved into a new job recently at the Applied Cloud Computing Lab in HP Labs Singapore. My first task was to hire engineers to staff the lab and while the final numbers were not absolute, the number 70 was bandied around for the population of the facilities. We have half a floor at Fusionopolis, plenty of space really but the bone of contention was more delicately focused on more sanitary facilities i.e. the toilets.
The problem was that the whole floor shares a single pair of toilets (one for male and another for female of course). I was totally convinced that with 70 people in the office, we will reach bladder or bowel apocalypse, a disaster in the waiting. My other colleagues however were less worried — the other floors seem to be doing fine. It wasn’t as if we could do anything about it, no one’s going to magically add in new toilets for us no matter how long the toilet queue was; but I had to know. I was also curious of course — what is the algorithm used to determine the number of toilets per square meter of occupancy?
Looking up building regulations found nothing (at least not online) in Singapore but UK has some regulations covered by the Health and Safety Executive.
Looking at facilities used by men only:
| Number of men at work | Number of toilets | Number of urinals |
| 1-15 | 1 | 1 |
| 16-30 | 2 | 1 |
| 31-45 | 2 | 2 |
| 46-60 | 3 | 2 |
| 61-75 | 3 | 3 |
| 76-90 | 4 | 3 |
| 91-100 | 4 | 4 |
Well, the toilets seem to almost fit into the UK regulations, but these are just regulations. How did these numbers come about and how realistic are they? To better model the usage scenarios, I did a Monte Carlo simulation on the usage pattern of the toilets, based on a simple set of assertions.
Taking an educated guess of 1 in 7 of engineers to be female, that leaves us with 60 male engineers sharing a single toilet facility. The toilet facility has 3 urinals and 2 stalls, one of which is a flush toilet, the other is a squat toilet (which in general no one uses any more).
An important piece of information is to find out how many times an average person need to urinate a day. It turns out that our bladder will signal us to make a trip to the toilet when it fills up to about 200ml. Combine with the information that an average urine output of an adult is 1.5 liters a day, this means that we roughly need to go about 8 times a day. This in turn means 8 times in 24 hours or 1 time in 3 hours on an average. The normal working hours in HP are 8:30am – 5:30pm, which is 9 hours, so this means on an average a person makes a beeline to the toilet 3 times during the course of the working day in the office.
I modeled the scenario discretely, per minute. This means a person in the office would make a decision to go to the loo or not every minute within the 9 hours in the office, or 540 minutes. Coupled with an average of 3 times in 540 minutes, this means the probability that a person would go to the toilet every count of the minute is 3 out of 540. In the case of urinating, my estimate is that a person will be able to complete the necessary job within 2 minute on an average and vacate the facility.
Armed with this model, let’s look at the simulation code:
require 'rubygems'
require 'faster_csv'
# population of 60 people on the same floor
population = 60
# period of time from 8:30am -> 5:30pm is 9 hours
period = 9
# 8 times a day -> 8 times in 24 hours -> 1 time every 3 hours
# within a period of 9 hours -> 3 times
# probability in every min -> 3 out of 9 * 60
times_per_period = 3
# rate of servicing
mu = 2
# number of people in the queue
queue = 0
# number of stalls available
stalls = 3
# number of occupied stalls
occupied = 0
# total of all queue sizes for calculating average queue size
queue_total = 0
# max queue size for the day
max_queue_size = 0
FasterCSV.open('queue.csv', 'w') do |csv|
csv << %w(t queue occupied)
(period * 60).times do |t|
# at every rate of service interval, vacate any and all people from the toilet and replace them with people in the queue
if t % mu == 0
occupied = 0
while occupied < stalls and queue > 0
occupied += 1
queue -= 1
end
end
population.times do
# does the engineer want to relieve himself?
if (rand(period * 60) + 1) <= times_per_period
if occupied < stalls
occupied += 1
else
queue += 1
end
end
end
csv << [t, queue, occupied]
max_queue_size = queue if queue > max_queue_size
queue_total = queue_total + queue
end
end
puts "** Max queue size : #{max_queue_size}"
puts "** Total mins in queue by all : #{queue_total} mins"
Most of the code are quite self explanatory. However notice that mu is 3 (minutes) instead of 2 as we have discussed earlier. The reason for this is that in keeping the simulation code simple, I’ve not factored in that if we clear the toilets every 2 minutes, people who entered during the 2nd minute (according to the simulation) will be cleared in just 1 minute. To compensate for this, I use a mu variable that is 1.5 times the service rate.
The simulation writes to queue.csv, which contains the queue size and toilet occupancy at every interval. This are the results:
** Max queue size : 3 ** Total mins in queue by all : 17 mins
I opened the CSV up and used the data to create a simple histogram:
| Queue size |
Number of minutes |
Percentage |
| 0 | 526 | 97.6% |
| 1 | 9 | 1.8% |
| 2 | 3 | 0.4% |
| 3 | 2 | 0.2% |
From the results it’s pretty obvious that the architect and engineers who built Fusionopolis knew their stuff. These were the quantitative conclusions:
- Queues were formed less than 3% of the time of the day
- The maximum number of people in the queue were 3 people and that happened for only less than 2 minutes in a day
- The total time spent by everyone in the office, in a queue to the toilet was 17 mins
This is for the men’s urinals, let’s look at the stalls now. The same simulation script can be used, just changing the parameters a bit. Instead of mu = 3, we use mu = 8. Instead of 3 urinals, we have 2 stalls and instead of 3 times over the period, we use 1 time over the working period.
These are the results:
** Max queue size : 3 ** Total mins in queue by all : 81 mins
| Queue size |
Number of minutes |
Percentage |
| 0 | 485 | 89.8% |
| 1 | 33 | 6.1% |
| 2 | 21 | 3.9% |
| 3 | 1 | 0.2% |
The problem seems a bit more serious now though not significantly so, though the chances of being in a a queue are higher now (10%).
In conclusion, I was wrong but I’m glad to be wrong in this case. Waiting in a toilet queue is seriously not a fun thing to do.
What if a group of engineers went out to have lunch and the food was spoiled? :P
For comparison, our site has somewhat more male engineers (probably around 100 between our company and two others that share the floor), with just two stalls and two urinals. This leads to more contention than the example. Fortunately, the floor above is underutilized and the facilities are right next to the stairs, so actual queuing is relatively rare…
goodwind89: yeah, I was wondering about a DOS attack as well.
In order to make the calculation worthy for the Applied Cloud Computing Lab, it should include a case with the average number of food poisoning taken into account. Then it should determine wether the resources on the other floors are sufficient to take care of the worst-case scenario.
This is a case where fighting for resources must be avoided by all costs.
Even when calculating with the resources on the other floors, we will end up with a very finite number of “servers” here.
It is because you need to take the routing time very seriously. Reaching the backup server must be possible within a very short period of time.
Dropping packets is absolutely not an accepted scenario.
I think I should stop now.
I think your assumptions are flawed.
Firstly, toilet trips are most definitely not randomly distributed over the course of the day. There will be a “run” on the facilities (if you’ll excuse the expression) around half an hour after lunch. You’ll have seen this if you’ve ever taken an intercontinental flight.
Secondly, having to wait for a #1 is most often a non-issue. But having to wait for a #2 is best case quite uncomfortable and worst case quite messy.
There’s also the cleanliness issue. Four toilets cleaned once a day are half as dirty on average as two toilets cleaned once a day.
Hi Robert, you’re right. My assumptions is unrealistic as you’ve pointed out. The simulation can be tweaked to take that into account. I’ve considered this point when I was writing this up but I only had a couple of hours to burn at night so I took the easy way out. Will be putting that in the next chance I have and re-post my findings.
Thanks for the tip!
And of course, my assumption that individual urinals are used with equal frequency is false, because of this:
http://blog.xkcd.com/2009/09/02/urinal-protocol-vulnerability/
How much time do nerds need to spend thinking about toilet habits, anyhow? :-)
I think you had a little too much time. :P
Aggie #1 is using the outhouse when a quraetr falls from his pocket into the pit.He moans and gnashes his teeth to Aggie #2 about the loss, then turns around and tosses a 20 dollar bill into the pit. Why did you do that? Aggie #2 asks. You don’t think I’m going in there for just a quraetr! Aggie #1 answers.