Liveblog: a Mars landing watch party with school kids

Yesterday, NASA landed its InSight mission on Mars, and it all worked! The landing happened between 8 and 9PM local time, but I wanted to share the excitement with my kids’ classmates from school (aged between around 9 and 10), so I needed something that worked remotely.

NASA provided a wonderful webcast in English, and although many children here in The Netherlands can follow that, I expected the stream to need more narration for the kids to truly experience the excitement of landing on another planet. Because this was the goal: spread some of that science love!

As an experiment, I hosted a somewhat quirky liveblog: the landing webcast in the middle, the opportunity to ask questions on the right, and my answers on the left.

screenshot (note - if all you care about is the technology, please scroll down to read about HTTP/2 and asynchronous webservices!)

In peak, we had 70 simultaneous viewers of the webcast, and dozens of questions were asked and answered. I got a lot of great feedback from parents & children, and I noticed that several kids really got hooked, some of whom I had not expected to be enthusiastic.

I think the experiment was successful, but part of this was not by design but due to accidental features of the liveblog. I want to document some of the learnings in this page should someone else want to do a “liveblog watch party” with kids.

Note that I describe the technology used at the end. Contact me ( if you want to host such a liveblog for a science event, or if you are technical enough, use the open source software I present below.

How it worked

I gave the school fliers telling people to go to from a desktop, tablet or laptop. I also told them it would be cool to mirror this to TV using Chromecast or Apple TV, and several families did so.

I had briefly tried to squeeze webcast, questions and answers onto a phone-sized experience, but it did not work out. This needs a bigger screen.

No sign-on was required, no passwords. Just load the page. If you want to ask a question, you’d have to enter a name, and press enter.

Before the actual landing, I made the page show a YouTube movie previewing the launch. Once the landing broadcast was close to starting, I refreshed the page for everyone to show the countdown to the start of the program & the actual webcast.

Now, if you give people the opportunity to post messages with no sign-on and complete anonymity, bad things usually happen. Inviting 30 children only makes this slightly worse. Because of this, I had created the rapid one-click ability to remove messages, with no fuss. In the course of the event (90 minutes), I probably removed over 75 messages, which then instantly disappeared from all screens. With two exceptions, these messages weren’t very bad, they just filled the screen with rocket emojis mostly.


Note that kids’ emoji skills are impressive, and it was fortunate I had made sure they would work.

A key, but weird, concept was separating the input from the audience from my answers. You’d normally somehow put these inline, or thread them. My programming abilities did not extend to creating threading. But the net effect was a column on the left full of (hopefully) educational answers and otherwise entertaining messages, plus a rowdy stream of questions & remarks on the right. This somehow worked.

Also relevant - I made it possible to post clickable links for the moderator, but not for the participants, which is somewhat of a security measure.

What did not work

Most of the 75 messages that had to be deleted (because of clutter) came from two or three kids who were just too rowdy. The system could have benefited from being able to ‘snooze’ some participants, perhaps even without them knowing their contributions were no longer making it to other people’s screens (‘shadowban’).

Also, I lacked the ability to paste pictures to illustrate points or show things. And while I could post links, it turned out that overly long links broke up the formatting of the page. So links should be shortened, and it should be possible to paste images as part of answers.


If you do this, you had better know your subject! Kids can ask a lot of questions, and you need to answer them quickly. The technical design of the liveblog had the possibility of supporting multiple moderators and this might in fact be a very good idea. You could have one person look up answer to a question while someone else fields easier or other questions.

After 90 minutes of moderating & answering questions, I was exhausted. 70 simultaneous visitors may be the maximum per moderator.

Summarising (features)

So in short:

  • No sign-on, no passwords
  • Be able to change the webcast being shown “on the fly”
  • Rapid & easy deletion of clutter and offensive messages
  • Emojis!
  • Separate answers & news from questions
  • Missing: ability to paste images
  • Bug: long URLs mess up the formatting
  • Missing: ability to ‘snooze’ certain participants


This part is for technical people that want to run liveblog software.

A live-blog is technically demanding. To provide instant updates to everyone, including deletions, requires a special web server. This is not something that you can whip up with a few modules.

I looked at various options to make this happen, but most of these were from commercial companies that required me to sign up with phone numbers and everything, which from experience means salespeople will start haunting me.

I also found Sourcefabric’s Live Blog but its installation manual has to be seen to be believed. Call me old-fashioned, but I’m not too hot for software that only runs in Docker and a very specific version of Elastic.

So I decided to write my own liveblog software, and I think it turned out rather well. It is open source and available on GitHub. Besides ’not invented here’, I had other reasons too: learning more about some of the dependencies I used.

powerblog dependencies:

  • libh2o: modern web development means HTTP/2 and TLSv1.3 and asynchronous queries. I’ve recently been using and documenting libh2o and I like it a lot
  • jquery: it is not the best, it is not the worst, and I know how it works
  • JavaScript Cookie: easily set & query cookies. Used to remember someone’s username over reloads & to recognize the administrator.
  • JSON for Modern C++: very much a “do what I mean”-compatible JSON library for modern C++.
  • sqlite_orm: This is a rather miraculous modern C++ ORM for SQLite. It is so much fun to use & safe too. Everything turns into a prepared query, not a SQL statement in sight. It installs and upgrades schemas too.

Because of the use of an ORM, powerblog is effectively stateless, and can be started and stopped at will. There are no blog contents in memory.

The web application

There are various ways to do ’live’ updates on a website. Very karmic is the use of Websockets, but I did not have time to explore that. Websockets also need a fallback in case of proxies that don’t do these newfangled things.

The other way is to make the browser do a GET request for new updates.. and have the web server not send an answer until there actually IS an update. If the request times out, use a .fail() promise to immediately send a new request. To prevent the duplicate delivery of events, each GET includes an event counter what events it is interested in (’everything since event 234’). If the web server has an event 235, it returns that immediately. If not, it lets the HTTP request hang there until it does.

This technique turns out to work very well. I added two enhancements - in case a post was removed, we also make all the GET requests respond, but not with the requested new event, but the full list of posts we have left, plus an indicator old posts should be removed from the screen. This turned out to be fast enough at the scale I was using it at (~700 events).

Secondly, because I wanted to be able to force a full page reload for users (for example to change the webcast URL), I added a special event for a restart, which triggers a call to location.reload().


To become administrator (and moderator), admin.html is used to set a cookie with the administrator password. When the powerblog sees this cookie with the correct password, it allows calls that delete posts, or trigger a full site reload.

Using powerblog

First, make sure you have installed libh2o-dev. Then check out the powerblog source & compile:

$ git clone --recursive
$ cd powerblog
$ make -j2

This will deliver a single binary called powerblog which when launched:

  • Binds to, forwards everything to https
  • Binds to, offers API there and..
  • Will serve files from ./html
  • Creates a sqlite3 file called ./powerblog.sqlite
  • Reads certificate and key from ./fullchain.pem and ./privkey.pem.

It is a pretty rough tool, but it does get the job done.

Let me know if you want to use it in earnest!