“When you do things right, people won’t be sure you’ve done anything at all.” -Futurama

After five years Nyx (previously known as arm) has gotten a long belated update. Under the covers our whole codebase has been rewritten from the ground up, but for users changes are subtle…

  • New website
  • Python 3.x support.
  • Bandwidth graph now prepopulates when you start up, so you have a graph right away.
  • Connections are now available without toggling DisableDebuggerAttachment in your torrc.
  • Support for showing IPv6 connections.
  • Dialog for picking tor events to log, rather than an arcane letter flag input.
  • Improved efficiency of log deduplication by multiple orders of magnitude. As such verbose logs no longer peg your CPU.
  • Richer control interpreter, including a python prompt like IDLE.
  • Removed features that frequently confused users such as the relay setup wizard and torrc validation.
  • Modernized dependencies, replacing TorCtl with Stem.

Hand-in-hand with Nyx I’m also pleased to announce Stem 1.6! A full year of improvements including descriptor creation support, ed25519 certificates, sizable performance tuning, and much, much more.

So how do I get started?

It’s easy! Just configure tor to accept a controller

% cat ~/.tor/torrc
ControlPort 9051
CookieAuthentication 1

… install Nyx…

% sudo pip install nyx

… and run!

% nyx


Oh how I love Sol Duc. Hundreds of miles of trails, white birch groves, and of course sulfuric hotsprings. Rainforest moss lends the woods an unearthly charm that’s truly just delightful.

Highlight of this month for me was a vacation with my dad, first to Port Townsend then Sol Duc. But this has been an interesting month on other fronts too.

Nyx Performance

This month my chief focus has been tuning Nyx. CPU usage is now 20% lower, and far more responsive under verbose logging due to constant time log deduplication. Overall Nyx finally looks ready for release. I’ll probably move forward with a call for beta testers after the dev meeting.


This month tor ratified a policy for internal list membership. Much of it just formalizes procedures we’ve used for a while, but it also adds a requirement on continued involvement to stay subscribed. Naturally volunteers move on to other projects over time and this perfectly fine, but eventually their membership will be suspended with re-addition fast tracked if they return.

I’m now facilitating discussions with the Vegas leads and Council on how best to determine this. To give us a starting point I put together some fun stats, but numbers alone don’t come anywhere close to answering the question of “how has this person been involved in making tor better in the last six months?”. Discussions ongoing.

Hi all. This month been down in the engine room productionizing Nyx, with a special focus on memory usage. Dropped ~13%, but still not where I want so investigations are ongoing.

Nyx SQLite Cache

Main benefit came from moving cached consensus information from memory to SQLite. Besides the obvious memory benefits this allows the cache to persist between invocations, halving Nyx’s startup time (from 0.7 to 0.3 seconds).

Tor Manual Database

Stem provides easy programmatic access for Tor’s manual information. SQLite now backs this information, providing 8x faster reads (Manual.from_cache() dropped 16ms to 2ms), and now supports random access reads…

>>> import stem.manual
>>> print(stem.manual.query('SELECT description FROM torrc WHERE key=?', 'CONTROLSOCKET').fetchone()[0])
Like ControlPort, but listens on a Unix domain socket, rather than a TCP socket.  0 disables ControlSocket (Unix and Unix-like systems only.)

This further drops Nyx’s memory usage by allowing it to only fetch the manual information it needs.

Stem Multi-Processing

May’s test performance investigation has now led to a general purpose DaemonTask class to make Python multi-processing easy…


import threading
import time

def fibonacci(n):
  if n < 2:
    return n
    return fibonacci(n-2) + fibonacci(n-1)

# calculate fibonacci sequences four times in parallel

start_time, threads = time.time(), []

for i in range(4):
  t = threading.Thread(target = fibonacci, args = (35,))


for t in threads:

print('took %0.1f seconds' % (time.time() - start_time))
% python fibonacci_threaded.py
took 21.1 seconds


import stem.util.system
import time

def fibonacci(n):
  if n < 2:
    return n
    return fibonacci(n-2) + fibonacci(n-1)

# calculate fibonacci sequences four times in parallel

start_time, threads = time.time(), []

for i in range(4):
  threads.append(stem.util.system.DaemonTask(fibonacci, (35,), start = True))

for t in threads:

print('took %0.1f seconds' % (time.time() - start_time))
% python fibonacci_multiprocessing.py
took 6.2 seconds

Presently this is only used for our tests, but soon I'll take advantage of this to make Nyx more performant on multi-core systems.

Hi all. This month pretended to be a web developer and made pretty things. Not an area I dabble in often but it was fun doing something artsy.

New Nyx Website

My eyes, they bleed! Made arm’s old site back in my college days and it shows…

old arm site

I’m delighted to announce Nyx’s new site is now live! New paint job aside our new site describes Nyx’s features, adds a FAQ, and better changelog.

new nyx site

Tor People Page

So many new people. Between newhires and new volunteers Tor is growing quite a bit right now and a common complaint I’ve heard is that our community makes it maddeningly hard to figure out who’s who. For some of us this is intentional, but others it’s not…

Who’s that arma guy I was talking with on irc? He seemed nice. Ok, thanks. Now which of these meeting attendees is Roger? Great. And, what does he do?“. Multiply that by ninety of us and it’s no wonder we drive our lovely hair-pulling newcomers to early baldness.

For those that would care to take part our people page now provides irc nicks, descriptions, pgp keys, twitter handles, and pictures. Hope this helps ya get a better idea of who those disembodied voices on irc are!

new nyx site

Hi all! Things I’m jugging are still in the air so this will be short. So what did I do this month besides buy a very, very manly puffer fish?

… sorry, those buggie eyes keep making me smile.

Migrate BridgeDB to Stem

Stem can now sign server and extrainfo descriptors! This was the last bit we needed for Leekspin parity. Isis and I are now swapping BridgeDB over.

After that’s been merged for a week or so I’ll likely cut the Stem 1.6 release. We have quite a few improvements accumulated so it’s about time…

Smaller things this month include…

Oh, and of course attended a local Retro Gaming Expo, Fremont Festival, great performance of Cabarat, and a coworker’s BBQ. Hope everyone else is having a similarly fun summer!

Hi all! Wanted to get my Pycon trip report out first but work keeps preempting that, so time to stop blocking. Lot of great stuff! But I suppose considering we’re already half way into June that’s no surprise…

Pycon and Stem Test Performance

Stay tuned for the full report, but highlights for me were discovery of mypy and multiprocessing.

Mypy is a static type checker with output similar to pyflakes or pycodestyle. Beginning with Python 3.5 core language syntax adds optional type information, and prior versions can provide this with comments. Mypy checks that function invocations match these types, providing type checks similar to what you’d get from static compilers like java.

I spent a bit integrating mypy with stem’s test suite but concluded it’s not ready for prime time quite yet. Mypy’s site cautions it’s still in early beta and indeed quite a few parts of stem (like enums) trip it up.

Multiprocessing on the other hand has been a big help.

Mulitprocessing is a python builtin that provides thread-style invocation of subprocesses. This is particularly interesting to me because for months I’ve struggled against the GIL for speeding up Stem’s tests. Multiprocessing is designed for just that, providing easy parallelization across cores.

Time since Pycon’s been spent integrating multiprocessing into our test suite, adding an @asynchronous decorator that invokes tests via subprocesses. On my antique dual core system this drops our test runtime from 53 to 22 seconds (58% faster). Should get even more on modern systems.

Evenings hit the Portland sights and tasty, tasty alcohol with my dad. Oh, and of course discussed Tor with Guido. It was a very fun trip.

Descriptor Creation

Stem and BridgeDB have always supported descriptor creation for their tests, with Isis even going the extra mile to make Leekspin. Taking the best of both Stem now supports a simple create() and content() function on descriptor classes…

RelayDescriptor.create({'router': 'demo 80 0 0'})

Leekspin’s still the only game in town for descriptor signing, but I hope to incorporate this soon too. You can read up more on this feature in our tutorials.

Couple other things this month include…

  • Stem now validates tor consensus signatures. Many thanks to Tyler Parks for all his help making this happen!
  • Passed GSoC administration on to Colin. Well past due we had fresh blood here.

Hi all. Emergent work encroached into my weekends a bit so less progress on my projects. On the nice side though had fun writing a PoE build and saw Cirque Du Soleil: Luzia with my family.


As always their performance was fantastic.

Tor Internal Bylaws

Alison’s Social Contract passed, and we’re presently in the process of electing a new Community Council. To this end helped conduct a candidate Q&A.

For a variety of reasons some folks would prefer not to vote. Some don’t have time, while others feel uncomfortable with voting due to their position in TPI or Tails. As such we’re now allowing folks to opt-out of counting toward the quorum requirement if they want.

tor-prompt –run

Stem’s tor-prompt command now supports a –run argument to run individual commands…

--run example

… listen to a space separated list of events with –run ‘SETEVENTS [event_types]’

--run example for events

… pipe its output to other destinations…

--run example for piping

… and invoke files with a series of commands…

--run example for files

Damn I love old architecture. Amsterdam’s venue was my favorite yet. Thanks Jon for setting it up!

Tor Developer Meeting

Beautiful city, neat hotel, among the best venues yet. On the tor front focused on community governance. Tricky topics are best discussed in person, and for me highlights were chats with Jens and Pepijn. Both expressed concerns regarding our community council in the past so this was a great opportunity to pick their brains. Jens especially had some great ideas for making the process even better.

Meeting aside saw the canals…

… Van Gogh museum…

… sat inside a giant clog…

… and of course found a large condom store next to snortable coca powder.

Amsterdam left me very confused.

Community Council

Proposal passed! Thanks to Alison and Tim for all their hard work. You can peruse our ratified community council policy here.

Ed25519 Certificate Support

In collaboration with Patrick O’Doherty added Stem support for parsing Ed25519 certificates.

When PyNaCl is present these certificates are used to check the integrity of server descriptors if you parse with validation.

Jury duty this month, but that was more than made up for with tasty, tasty pizza – thank you Shari! February had lots of great stuff.

Google Summer of Code

We have been accepted!

Got a project to pitch? It’s not too late! Students are already rolling into irc so if you want to mentor this summer the sooner you let me know the better.

Community Council

Tag teaming with Alison on a formal proposal for our community council. Initial council attempt hit some potholes but I’m glad for it since it’s given us a much better idea of what we want the council to become.

Fingers crossed that it’s successful!

Besides this just a handful of Stem changes…

  • Patrick migrated our cryptographic descriptor validation from pycrypto (which is unmaintained) to cryptography.
  • Further sped up our tests. Unit and integ tests now run 15% faster, and @only_run_once is fixed so the ‘RUN_ALL’ target is dramatically faster.
  • Corrected unesacaping of controller responses. Thansk to this authentication cookies with non-English characters in their path now work.

See ya all in Amsterdam!

Oh for the love of… I’m having horrible luck this winter. Third bug to knock me out. From the fever guessing this one was the flu. Ok virulent antigens, you’ve had your fun with Damian. Time to leave him alone now…

None the less, this was a good month.

Tor Internal Bylaws

We finally have a ratified voting policy!

Thanks everyone! Alison and I will put together some initial proposals but first gonna take a little breather.

Stem Test Speed

During my morning commute I’ve been poking at Stem’s test performance. Faster tests mean quicker development cycles. Always a good investment.

This took some unexpected turns resulting in…

  • 22% faster integration tests.
  • 25% faster descriptor parsing when validating.
  • Our stem.util.test_tools module now provides a TimedTestRunner class that gives individual test runtimes. Sadly this is something Python’s built-in unittest module doesn’t have.You can run our tests with the ‘–verbose’ argument to see this information…

    verbose test output

Other neat things this month include…