Simple Encryption In Dart


This post covers simple, symmetric key encryption using Dart. If you don’t know much about encryption and you’re looking for a basic “password” encryption solution, this is the post for you.


You need to encrypt and later decrypt some data with a password. So

  • What library do you use?
  • What encryption algorithm do you use?
  • Are there code samples?
  • What does the terminology mean?

I had these problems recently. Dart has some great encryption libraries. The biggest problem for me was finding the right library to use. Once I did, the documentation was horrible. Being a newbie at encryption, I also didn’t understand the terminology, and the code samples weren’t great.


  • Symmetric key cryptography – This means you have one password to encrypt and decrypt. If different people or computers are doing the encryption and decryption, you need to figure out how both people/computers will get the same password securely. This is a big problem in many cases, which is why Asymmetric keys (i.e. public and private keys) are more popular now. This post covers symmetric keys.
  • Algorithm choice. You can’t just use any encryption algorithm. RSA encryption, for instance, uses asymmetric keys, and therefore is not suitable for this use case. This post covers AES-GCM 128-bit. This is one of the most trusted solutions. For greater security, you can use 256-bit instead. This will mean adjusting your key (password) size, but the rest should be the same.
  • Key – key means password in this case. For 128-bit AES-GCM, you need a 128-bit key. That’s 16 bytes. The rust code will panic if you do not provide exactly 16 bytes for the key. If you use 256-bit AES-GCM, you will need a 256-bit, or 32 byte, key. There is a padding option with some algorithms. I am not using it. I am performing my own padding. The padding function is included in the code sample.
  • Nonce/IV – Nonce and IV (for this algorithm) are the same thing. Nonce means “number only used once”. IV means “initialization vector”. Some posts and libraries use the word nonce, others IV. Don’t be confused by the change in terminology. The nonce/iv is the seed used in random number generators. Traditional random number generators use one number only (eg. 8-bit or 32-bit) as the seed. AES-GCM needs a 96-bit, or 12 byte, seed. This is supplied as a list of 12 bytes. Again, if your seed length is incorrect, the library panics. The nonce/iv used for encryption is needed for decryption.
  • Cipher Text – This is the encrypted data. It will be exactly the same length as the unencrypted data.
  • MAC – this is a list of numbers calculated after encryption. It is needed for decryption. It is 16-bytes long for 128-bit AES-GCM.
  • AAD – additional verification data. I don’t need it so I didn’t bother using it.

Encryption Process

  • Create a new IV/nonce
  • Ensure your key is the correct length. I provide a padding function so if the key is less than 16 bytes, it is padded with 0x00. If it is more than 16 bytes, it is truncated.
  • Convert your data to encrypt, and your key, to a list of bytes
  • Initialize the library and call encrypt(). The result will be the encrypted data (cipher text) as a list of bytes (exactly the same length as the unencrypted input), and a 16-byte mac.
  • You then need to return the nonce, the cipher text, and the mac. All three values are required for decryption. I hex encode this data before returning so it can easily be used in places like JSON messages. I’m sure there is an industry standard for passing around this information. However, the encoding system I’m using is my own, and not official.

Decryption Process

  • You need the nonce/iv, the cipher text and the mac values to perform decryption, along with the password. In my example, all this data is hex encoded. I have provided a function to decode (not decrypt) this hex encoded information, and extract the relevant values
  • Initialize the library and call decrypt() with the values above
  • The result will be a List of bytes. You can process this list however you want eg. in my example, I just convert it to a string and display it.


Add the following dependencies:

name: test_aes_gcm_dart
description: A sample command-line application.
version: 1.0.0
# homepage:

  sdk: '>=2.18.5 <3.0.0'

  cryptography: ^2.0.5

  lints: ^2.0.0
  test: ^1.16.0
  hex: ^0.2.0


import 'dart:convert';

import 'package:hex/hex.dart';
import 'package:cryptography/cryptography.dart';

/// Pads the password if necessary.
/// The final password must be exactly 16 bytes. If the input password is less than 16 bytes, it will be padded with 0x00.
/// if it is more than 16 bytes, only the first 16 bytes will be used.
List<int> getValidPassword(String origPassword, int maxLength) {
  var origBytes = utf8.encode(origPassword).toList();

  var len = origPassword.length;
  if (len < maxLength) {
    for (int j = 0; j < (maxLength - len); j++) {
  } else if (len > maxLength) {
    origBytes.sublist(0, maxLength);

  return origBytes;

/// Encrypt data with password. Password is the raw password (i.e. not hex encoded)
Future<String> encrypt(List<int> data, String password) async {
  final pwBytes = getValidPassword(password, 16);

  /* use 128 bit encryption. If you plan on using, eg. 256 bit, adjust the password length appropriately */
  final algorithm = AesGcm.with128bits();

  final secretKey = await algorithm.newSecretKeyFromBytes(pwBytes);
  final nonce = algorithm.newNonce();

  var secretBox = await algorithm.encrypt(
    secretKey: secretKey,
    nonce: nonce,
  //print('Nonce: ${secretBox.nonce}');
  //print('Ciphertext: ${secretBox.cipherText}');
  //print('MAC: ${secretBox.mac.bytes}');
  //print("mac length is: ${secretBox.mac.bytes.length}");

  var hexNonce = HEX.encode(nonce);
  var hexCipher = HEX.encode(secretBox.cipherText);
  var hexMac = HEX.encode(secretBox.mac.bytes);

  String encryptedString = "$hexNonce/$hexCipher/$hexMac";
  return encryptedString;

class DecodedData {
  List<int> nonce = [];
  List<int> cipherText = [];
  List<int> mac = [];

DecodedData decodeCipherString(String encryptedString) {
  List<String> split = encryptedString.split("/");
  if (split.length != 3) {
    throw Exception("Invalid cipher text size");

  String hexNonce = split[0];
  String hexCipher = split[1];
  String hexMac = split[2];

  DecodedData decoded = DecodedData();
  decoded.nonce = HEX.decode(hexNonce);
  decoded.cipherText = HEX.decode(hexCipher);
  decoded.mac = HEX.decode(hexMac);

  return decoded;

/// encryptedString must be in the format [hexNonce]/[hexCipher]/[hexMac].
/// password is just a string.
Future<List<int>> decrypt(String encryptedString, String password) async {
  List<int> pwBytes = getValidPassword(password, 16);

  final algorithm = AesGcm.with128bits();

  /* decode (not decrypt) */
  var decoded = decodeCipherString(encryptedString);

  var secretBox = SecretBox(decoded.cipherText, nonce: decoded.nonce, mac: Mac(decoded.mac));
  var secretKey = await algorithm.newSecretKeyFromBytes(pwBytes);
  final decrypted = await algorithm.decrypt(
    secretKey: secretKey,

  return decrypted;

void main(List<String> arguments) async {
  String data = "hello world";
  String password = "12345";

  print("Original message is: $data. Password for encryption/decryption is: $password");

  print("First, let's encrypt");
  String encryptedString = await encrypt(utf8.encode(data), password);
  print("Encrypted string is: $encryptedString");

  print("Now, let's decrypt");
  List<int> decrypted = await decrypt(encryptedString, password);

  /* we're expecting a string, so convert to a string and output */
  String decryptedMsg = utf8.decode(decrypted);
  print("Decrypted message is: $decryptedMsg");

Hope this helps!

Simple Encryption In Rust


This post covers simple, symmetric key encryption using Rust. If you don’t know much about encryption and you’re looking for a basic “password” encryption solution, this is the post for you.


You need to encrypt and later decrypt some data with a password. So

  • What library do you use?
  • What encryption algorithm do you use?
  • Are there code samples?
  • What does the terminology mean?

I had these problems recently. Rust has some great encryption libraries. The biggest problem for me was finding the right library to use. Once I did, the documentation was horrible. Being a newbie at encryption, I also didn’t understand the terminology, and the code samples weren’t great.


  • Symmetric key cryptography – This means you have one password to encrypt and decrypt. If different people or computers are doing the encryption and decryption, you need to figure out how both people/computers will get the same password securely. This is a big problem in many cases, which is why Asymmetric keys (i.e. public and private keys) are more popular now. This post covers symmetric keys.
  • Algorithm choice. You can’t just use any encryption algorithm. RSA encryption, for instance, uses asymmetric keys, and therefore is not suitable for this use case. This post covers AES-GCM 128-bit. This is one of the most trusted solutions. For greater security, you can use 256-bit instead. This will mean adjusting your key (password) size, but the rest should be the same.
  • Key – key means password in this case. For 128-bit AES-GCM, you need a 128-bit key. That’s 16 bytes. The rust code will panic if you do not provide exactly 16 bytes for the key. If you use 256-bit AES-GCM, you will need a 256-bit, or 32 byte, key. There is a padding option with some algorithms. I am not using it. I am performing my own padding. The padding function is included in the code sample.
  • Nonce/IV – Nonce and IV (for this algorithm) are the same thing. Nonce means “number only used once”. IV means “initialization vector”. Some posts and libraries use the word nonce, others IV. Don’t be confused by the change in terminology. The nonce/iv is the seed used in random number generators. Traditional random number generators use one number only (eg. 8-bit or 32-bit) as the seed. AES-GCM needs a 96-bit, or 12 byte, seed. This is supplied as a list of 12 bytes. Again, if your seed length is incorrect, the library panics. The nonce/iv used for encryption is needed for decryption.
  • Cipher Text – This is the encrypted data. It will be exactly the same length as the unencrypted data.
  • MAC – this is a list of numbers calculated after encryption. It is needed for decryption. It is 16-bytes long for 128-bit AES-GCM.
  • AAD – additional verification data. I don’t need it so I didn’t bother using it.

Encryption Process

  • Create a new IV/nonce
  • Ensure your key is the correct length. I provide a padding function so if the key is less than 16 bytes, it is padded with 0x00. If it is more than 16 bytes, it is truncated.
  • Convert your data to encrypt, and your key, to a list of bytes
  • Initialize the library and call encrypt(). The result will be the encrypted data (cipher text) as a list of bytes (exactly the same length as the unencrypted input), and a 16-byte mac.
  • You then need to return the nonce, the cipher text, and the mac. All three values are required for decryption. I hex encode this data before returning so it can easily be used in places like JSON messages. I’m sure there is an industry standard for passing around this information. However, the encoding system I’m using is my own, and not official.

Decryption Process

  • You need the nonce/iv, the cipher text and the mac values to perform decryption, along with the password. In my example, all this data is hex encoded. I have provided a function to decode (not decrypt) this hex encoded information, and extract the relevant values
  • Initialize the library and call decrypt() with the values above
  • The result will be a List of bytes. You can process this list however you want eg. in my example, I just convert it to a string and display it.


Add the following dependencies:

name = "aes_gcm_128_rs"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at

hex = "0.4.3"
rust-crypto = "0.2.0"
rand = "0.8.5"


Here’s a full application that shows encryption and decryption. The code is well commented and despite being a little long, it should be very easy to understand.

use std::error::Error;
use std::{io, str};
use std::io::ErrorKind;
use std::iter::repeat;
use std::str::from_utf8;
use crypto::aead::{AeadDecryptor, AeadEncryptor};
use crypto::aes_gcm::AesGcm;

/// orig must be a string of the form [hexNonce]/[hexCipherText]/[hexMac]. This
/// is the data returned from encrypt(). This function splits the data, removes
/// the hex encoding, and returns each as a list of bytes.
fn split_iv_data_mac(orig: &str) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>), Box<dyn Error>> {
    let split: Vec<&str> = orig.split('/').into_iter().collect();

    if split.len() != 3 {
        return Err(Box::new(io::Error::from(ErrorKind::Other)));
    let iv_res = hex::decode(split[0]);
    if iv_res.is_err() {
        return Err(Box::new(io::Error::from(ErrorKind::Other)));
    let iv = iv_res.unwrap();

    let data_res = hex::decode(split[1]);
    if data_res.is_err() {
        return Err(Box::new(io::Error::from(ErrorKind::Other)));
    let data = data_res.unwrap();

    let mac_res = hex::decode(split[2]);
    if mac_res.is_err() {
        return Err(Box::new(io::Error::from(ErrorKind::Other)));
    let mac = mac_res.unwrap();

    Ok((iv, data, mac))

/// gets a valid key. This must be exactly 16 bytes. if less than 16 bytes, it will be padded with 0.
/// If more than 16 bytes, it will be truncated
fn get_valid_key(key: &str) -> Vec<u8> {
    let mut bytes = key.as_bytes().to_vec();
    if bytes.len() < 16 {
        for j in 0..(16 - bytes.len()) {
    } else if bytes.len() > 16 {
        bytes = bytes[0..16].to_vec();


///Decryption using AES-GCM 128
///iv_data_mac is a string that contains the iv/nonce, data, and mac values. All these values
/// must be hex encoded, and separated by "/" i.e. [hex(iv)/hex(data)/hex(mac)]. This function decodes
/// the values. key (or password) is the raw (not hex encoded) password
pub fn decrypt(iv_data_mac: &str, key: &str) -> Result<Vec<u8>, Box<dyn Error>> {
    let (iv, data, mac) = split_iv_data_mac(iv_data_mac)?;
    let key = get_valid_key(key);

    let key_size = crypto::aes::KeySize::KeySize128;

    // I don't use the aad for verification. aad isn't encrypted anyway, so it's just specified
    // as &[].
    let mut decipher = AesGcm::new(key_size, &key, &iv, &[]);

    // create a list where the decoded data will be saved. dst is transformed in place. It must be exactly the same
    // size as the encrypted data
    let mut dst: Vec<u8> = repeat(0).take(data.len()).collect();
    let result = decipher.decrypt(&data, &mut dst, &mac);

    if result { println!("Successful decryption"); }
    println!("\nDecrypted {}", str::from_utf8(&dst).unwrap());


/// Creates an initial vector (iv). This is also called a nonce
fn get_iv(size: usize) -> Vec<u8> {
    let mut iv = vec![];
    for j in 0..size {
        let r = rand::random();


///encrypt "data" using "password" as the password
/// Output is [hexNonce]/[hexCipher]/[hexMac] (nonce and iv are the same thing)
pub fn encrypt(data: &[u8], password: &str) -> String {
    let key_size = crypto::aes::KeySize::KeySize128;

    //pad or truncate the key if necessary
    let valid_key = get_valid_key(password);
    let iv = get_iv(12); //initial vector (iv), also called a nonce
    let mut cipher = AesGcm::new(key_size, &valid_key, &iv, &[]);

    //create a vec of data.len 0's. This is where the encrypted data will be saved.
    //the encryption is performed in-place, so this vector of 0's will be converted
    //to the encrypted data
    let mut encrypted: Vec<u8> = repeat(0).take(data.len()).collect();

    //create a vec of 16 0's. This is for the mac. This library calls it a "tag", but it's really
    // the mac address. This vector will be modified in place, just like the "encrypted" vector
    // above
    let mut mac: Vec<u8> = repeat(0).take(16).collect();

    //encrypt data, put it into "encrypted"
    cipher.encrypt(data, &mut encrypted, &mut mac[..]);

    //create the output string that contains the nonce, cipher text, and mac
    let hex_iv = hex::encode(iv);
    let hex_cipher = hex::encode(encrypted);
    let hex_mac = hex::encode(mac);
    let output = format!("{}/{}/{}", hex_iv, hex_cipher, hex_mac);


fn main() {
    let data = "hello world";
    let password = "12345";

    println!("Data to encrypt: \"{}\" and password: \"{}\"", &data, &password);

    println!("Encrypting now");
    let res = encrypt(data.as_bytes(), password);
    println!("Encrypted response: {}", res);

    println!("Decrypting the response");
    let decrypted_bytes = decrypt(res.as_str(), password).unwrap();
    let decrypted_string = from_utf8(&decrypted_bytes).unwrap();
    println!("Decrypted response: {}", decrypted_string);

Hope this helps!

Rust, Mutexes, and Mutating Data in Re-entrant Mutexes

TL;DR it is possible to have re-entrant mutexes in Rust, and mutate data. This article summarizes what to do, but a simple code example is available Read the code, it’s very easy. The example is fully commented and uses println!() statements to explain everything written below.

Rust offers a variety of tools for multi threaded and concurrent programming including mutexes. But the mutexes included in the standard library leave a lot to be desired. If you come from a Java or C background, for instance, you’re probably familiar with re-entrant mutexes. These mutexes can be locked numerous times by the same thread without deadlocking. That feature can often simplify multi-threaded or concurrent code significantly.

Thankfully, the parking_lot crate solves that problem. Swap out std::sync::Mutex for parking_lot::ReentrantMutex and you have an an almost drop-in replacement that’s fully re-entrant. I say “almost” because sync::Mutex.lock() returns a Result<> and requires an extra .unwrap(). But that’s really just nitpicking.

Unfortunately, parking_lot::ReentrantMutex only works for immutable data. There is no way of directly obtaining a mutable reference to the data protected by parking_lot’s ReentrantMutex. So what do you do when you need to change the data?

It’s RefCell to the rescue! Your protected data will likely end up looking something like this:

let shared_data = Arc::new(ReentrantMutex::new(RefCell::new(55)));

RefCell implements borrowing rules at runtime, not compile time. So data mutation is allowed, but the rules must be followed or else your code will panic!().

The sample project shows regular mutexes (from the parking_lot crate, but std::sync::Mutex can be used as well), re-entrant mutexes for immutable data, and finally re-entrant mutexes combined with RefCell to allow for data mutation.

Re-entrant mutexes have a performance penalty when compared to regular mutexes, but they simplify multi-threaded code enough that I consider it to be a worthwhile tradeoff, unless every nanosecond counts.


The Worst Month Of My Life

I was in Cusco, Peru, in late April, with around 10 days left before I planned to head north to Ayacucho, then Lima, and finally to Ecuador. Cusco is, without a doubt, one of the most beautiful cities I’ve ever seen, but I was looking forward to moving on.

Then, around 1:30am on a Tuesday morning, I awoke after sleeping for just 30 minutes with an upset stomach. I put it down to a mild case of indigestion but wasn’t able to fall asleep again as the discomfort got worse, but not to the point of calling it outright painful. I started my day a few hours later with a work meeting, all the while noting the discomfort had turned painful, though not much.

I resolved to take a walk around 10am in the hopes that the indigestion would pass. I was perhaps 2km from home when, in the space of maybe 5 minutes, I suddenly felt more dehydrated than I ever had before, with my lips suddenly on the verge of cracking. I grabbed a water and a taxi home, then chatted to a doctor friend of mine back in South Africa. The short version of her advice was “go to the hospital”.

I have no idea how I walked to the corner to catch another taxi. The pain was throbbing. When asked where I wanted to go, I just said “to the hospital” in my broken Spanish. The driver asked which hospital, and I said whichever was closest. Then he asked if I was a tourist. On nodding in the affirmative, he said he knew where to go and rushed me to a private hospital around 10 minutes away. 10 minutes of agony.

The hospital is called O2 Medical Network and caters to tourists, with staff that speak English sufficiently well that communication was not an issue. My broken Spanish is good enough to order a meal at a restaurant, but nowhere near good enough to describe a medical problem. A quick scan later revealed acute appendicitis, and emergency surgery required. It was my first time staying overnight in a hospital. I’m not a fan.

The surgery was simple enough, though my fever refused to subside so I remained in observation for a further 2 days, for a total hospital stay of 3 nights. While the pain had certainly lessened, it was by no means gone, but the surgeon assured me this was normal after an appendectomy.

I was released on Friday afternoon. Friday was horrible. I couldn’t sleep. I didn’t want to eat. I could barely stand. But I assumed things would improve over the next few days.

Saturday was worse. What was a mild pain at the hospital seemed to magnify exponentially, and by Sunday morning the pain was excruciating. I lay in bed dreading another hospital visit. Another night or three with a needle in my arm, unable to rest, bored out of my mind. But the pain was enough that I knew another hospital visit was required.

On Sunday morning I checked myself back into the hospital. A scan revealed my gallbladder was inflamed and full of stones. A second surgery was required. That would be two surgeries in 5 days. Once again the procedure was straightforward and thankfully this time, the pain had eased. After a further 2 nights, I was discharged.

Phase 1 was over. Phase 2, recovery, was just starting. I suppose it wouldn’t have been too bad if I’d had help, but I was alone. 23 hours a day in bed meant I had a constant headache. I had no appetite at all for the first 2 weeks, and realized after a few days that I felt so weak because I wasn’t eating. So I made a point of forcing myself to eat something, anything, at least once every 8 hours. That’s surprisingly difficult when you have no appetite. My energy levels, even after my eating regiment was put in place, were very low. Sitting up drained me. I dreaded walking to the table to eat. After 5 minutes I’d need to lie down again. Silly as it sounds, I’d make a plan in my head of all the effort I’d need to put in before leaving the table. 6 steps to the sink to drop off dirty dishes, 2 steps to the fridge to put away left overs, 4 steps back to the chair so I could rest. Then came the pep talk: “You can run 10km. This is just 12 steps. You can do 12 steps.” It wasn’t fun.

My recovery period, as per the doctor’s instructions, is meant to be 5 weeks after the second surgery. I have around 2 weeks left. Things have improved considerably. I can eat normally, and walk into town for dinner, though even moderate exercise is still enough to drain me thoroughly.

I’m hoping to be back on my bike this weekend. I can’t travel yet, but I think I’m ready to at least take a short ride around town. My visa will have expired before I leave Cusco; I already checked with migrations and it’s not possible to get an extension. I just need to pay a fine when I leave, and even that may not be required if I plead my case with the border guard. I still need to visit Aduanas (customs) to try and extend my motorcycle permit in the country.

And that brings us to 26 May 2022. My ordeal is far from over, but the worst of it is, and for that I am very thankful. I hope to be on the road again soon but for the next few weeks at least, I’ll be calling Cusco home.

Ramadan in Cusco, Peru

This is my 5th consecutive Ramadan away from South Africa. On the whole, it’s not a bad place to spend 30 days.

My Ramadan 2018 was spent in Kuala Lumpur, an amazing city for the auspicious month. 2019 found me in Uruguay, starting the fast in Montevideo and ending in Salto, with around 5 other cities covered in those 30 days. Then came Covid. Ramadan 2020 was spent in Buenos Aires, and was awful. The lockdown had only eased up very slightly, and the highlight of every day was walking 2 blocks to the supermarket. By the end of the month things had eased to the point where I would head to a verduleria (fruit and veggie shop) about 3-4 blocks away to buy as few bananas as a could so I would have an excuse to head out the next day as well. And 2021 was spent in Bariloche, Argentina, the most beautiful city in the country in my opinion. There was a 8pm curfew, but life was mostly back to normal by then. I prayed (literally prayed) that 2022 would find me anywhere but Argentina for Ramadan and …

I’m in Cusco, Peru. The Peru-Bolivia land border opened only a few weeks earlier, and I waited in La Paz until my Bolivian visa had almost expired before crossing Desaguadero (the town at the Peru-Bolivia border) and headed to Puno (small but nice), then Arequipa (big and nice), and finally to Cusco.

I arrived about 10 days before Ramadan started. I wanted to get a Machu Picchu trip in before fasting began, and the original plan was to spend only the first week of Ramadan here before moving on (that would be around 16 days in total). But I will be spending almost 6 weeks here, mostly for the reasons below.

Cusco is one of the most beautiful cities I’ve seen. Of course I’m referring to Plaza de Armas and the surrounding few blocks; perhaps a radius of 5 blocks, with Plaza de Armas at the centre. That’s the main tourist area and once you move beyond that, Cusco feels like most other South American cities, albeit with the occasional jewel scattered in some corner, usually in the form of a stunning view.

Views and beauty aside, the city has a lot going for it, from the point of view of someone looking to spend Ramadan here. Perhaps the biggest plus is the weather. Ramadan 2022 started in early April, smack in the middle of Autumn. The day temperature ranges from around 16 degrees Celsius at the low end, to 21 degrees on the high side. The colder nights are around 5 degrees, and the warmer nights around 12 degrees. There’s no uncomfortable gusts of Autumn wind, and humidity is not a problem. In short, just about the perfect weather for me. Had I moved on to Lima as originally planned, I would be facing 31 degree days with high humidity – far less appealing. I’m too lazy to do a Fahrenheit conversion, so Google for a converter if necessary.

Being a tourist town, restaurants stay open late, and much later than ifthaar. I often found myself breaking fast in a restaurant before rushing home for Maghrib. My pattern later changed to breaking fast at home with just water, reading Maghrib, then heading out to a restaurant for a more relaxed meal. There are tons of restaurants with vegetarian and fish options so food was never a problem. And on the days I stayed home and cooked, finding groceries was never an issue. I also learned recently that at least one of the large supermarkets about 2km from where I live sells Halal chicken, complete with Halal certification. I have not verified this yet, but the information came from a very reliable source. Unfortunately, there are no halal restaurants in the city or nearby, and it appears there are no other halal meat options.

One unexpected bonus of being the in city is there is a Musallah not too far out of town, around 2.5km from Plaza de Armas, and accessible by taxi for around 6-8 Sols. You can find it on Google Maps by searching for either “Mosque” or “Musallah”, on Avenida Peru, close to Barrio Miraflores. Unfortunately I have a location only, not a street address. If it did, I doubt it would help much since there is no indication whatsoever that the building houses a Musallah. It looks like every other house on the street, and the entrance is a generic black metal door that I walked passed the first time I was there. The facilities are very basic, but they serve the needs of the local Muslim community. The people who run things are sincere, and welcome everyone, locals and foreigners alike, with open arms. Should you be interested in visiting, Jummah salaah is typically held at 13:30 sharp, so get there around 13:15. The Musallah closes after salaah, and everyone heads back to work, so don’t be discouraged if you arrive and find the place closed; just wait a while. One Friday everyone was running late and the Musallah only opened around 13:35. The people who run the place have jobs and other life commitments, and keep the Musallah going as well. They are hoping to expand their facilities if possible (maybe even turn it into a proper Mosque) since they have very little. Should you wish to help, contact me and I can perhaps put you in touch with someone in charge. I am not in any way officially associated with the organization. I have, however, experienced their hospitality for the last few weeks and overall, they seem like excellent folk, trying to do the best they can with what they have (including things like arranging Zakaat food parcels for anyone who wants it).

I am writing this with one week of Ramadan 2022 remaining. As someone who travels regularly, I am not fond of staying in one place, especially for 6 weeks in a tourist town like Cusco. But the combination of the city, the food, the weather, and the friends I’ve made these last few weeks, have made this one of the experiences I will remember in a very positive light, perhaps even fondly. It certainly beats the previous 2 years.

To Muslims looking to visit Cusco, Peru, I highly recommend it.


Once upon a time I used to write for fun, but I thought my old posts were long lost. I found one today, from around 2009! Maybe I’ll find more. But for now, here’s the thoughts of a 29-30 year old me …

Do you know what hair is? The sort that sprouts out the top of your head I mean. Hair is dead cells. As in not alive. Do you have any idea how depressing that is? Because as someone going bald it means that the dead are rejecting me. Death finds me too damn repulsive to stick around so even in their dead state, strands of hair from my head manage to somehow find enough energy to pop out and run the hell away. It’s natural for living things to cling on to life; nature designed our bodies to try and survive no matter what the circumstances. Yet my hair doesn’t have the energy to cling on to life but it musters up the strength to escape from my head. It really is the worst kind of rejection there is.

The thing is though, once you realize that your own body will run away from you if it had the chance you start wondering about other things. For instance when your parents told you they loved you and said seemingly innocent things when you were little like “you’re a big boy now, it’s time you slept in your own room”, were they doing it because they wanted to teach you to be independent, or were they just putting as much physical distance between you and them as they possibly could? After all let’s face it, if the dead are running away from you, the chances are pretty damn slim that your parents want you in the same room while they’re sleeping with the lights off. In horror movies, they always get you in the dark. So 10 metres, 3 doors and lots of brick and concrete is a comforting thought for parents I’m guessing.

But then, can we victims of male pattern baldness really be held accountable for any of this? For really, that’s precisely what we are: victims. We didn’t choose to go bald. We didn’t make ourselves repugnant. It’s the way we were made. Yet we’re forced to hide in the shadows and live lives of shame and mourning. We’re meant to feel the guilt and sorrow as each strand plucks its way to freedom from us; we who love every one of those strands and we who would gladly welcome them back to our barren scalps.

No, the truth is not that we’re repulsive. We’re accepting. We’re full of love, we’re caring, kind and compassionate. It’s the rest of you who should feel ashamed. You hair-headed elitists who feel compelled to judge and ridicule us for our decency. So I stand proudly here today, one in the sea of balding men and say NO to you and your kind. NO to your abuse. NO to your tyranny. NO to your hate.

I am a balding man. Hear me roar!

Please hear me roar, because nobody bothers looking at me anymore.

Getting Started With Tokio

This is a quick getting started guide to using Tokio, an async runtime for Rust. To understand this article, you need to:

  • understand at least the basics of Rust programming
  • understand at least some of the concepts behind parallel and concurrent programming
  • understand asynchronous programming with async/await

What is Tokio?

Tokio is an async runtime for rust. Rust supports async programming, but in the spirit of keeping the standard library small, it does not offer a great async runtime out the box. Instead, 3rd party tools like Tokio may be used instead. The obvious downside here is you need to learn about a 3rd party dependency, but the upside is you have choice, and if Tokio does not meet your needs, you can always use something else.

Tokio is probably the most popular async runtime at the time of writing this article (February 2022).

Concurrent vs. parallel

The short version

Concurrent means running multiple tasks in such a way that they look like they are all running at once, even though only one task is running at a time. A task is just a piece of code to run, like a function, or a lambda, or even an async block.

Parallel means running more than one task simultaneously e.g. running 2 threads at the same time, each on a different CPU core.

If you understand this, skip to the next section. If you are still a little confused, keep reading.

The longer version

Suppose you have 3 functions you want to run at the same time. Let’s call them:

  • async fn A()
  • async fn B()
  • async fn C()

Traditionally you would use threads. Each function will be started in a different thread, and the operating system will typically allocate each thread to a different CPU core if possible. So, if you have a 4-core CPU, it’s possible A(), B(), and C() are all running at exactly the same time. This is parallel processing.

Of course if you have a 2-core CPU, only 2 threads will run in parallel, and the operating system scheduler will eventually context switch to the remaining thread when possible (i.e. it will swap one of the running threads for the thread that’s not running).

If you have a single core CPU, then only 1 thread will be able to run at a time, so nothing will be running in parallel. That is, even though it will look like all 4 threads are running at once, the OS scheduler is really just switching between them really quickly to make it seem as though they are all running at once, even though they are running one after the other.

Another way of saying what happens to threads on a single core CPU is to say the threads are running concurrently. They can’t run in parallel because there’s only one CPU core!

Concurrency has the effect of parallel processing, without actually doing parallel processing.

Historically, it has been the job of the OS scheduler to achieve this effect, and the effect was achieved with threads. But more recently, people have created started doing multiple pieces of work concurrently on the same thread; sometimes called green threads.

The reason is simple: threads are expensive. Starting a thread is much faster and less resource intensive than starting a new application/process. But starting a green thread is much much faster, and even lighter on resources, than running a thread. So if you need to service thousands of network calls, for instance, running them on green threads places much less of a strain on the operating system, and you have huge performance gains.

The operating system does not handle green threads. And it would be silly if every programmer had to implement a green threading solution for themselves. Which is where async runtimes like Tokio fit it.

Tokio to the Rescue

Tokio is a runtime and once started, you can simply hand it tasks to complete. A task, as mentioned above, it a piece of code to run. Tokio calls these pieces of code tasks as well. Tokio will accept the task and run it in the background until it is complete. Tokio can accept multiple tasks, and can be configured to run on multiple threads. This means you can have X tasks running on Y threads, with almost no additional effort on your part.

Coding time


Add the following to your Cargo.toml:

tokio = { version = "1", features = ["full"] }
rand = "0.8.4"

Sample Code

Here’s some heavily commented sample code. The code will run 10 tasks in the background. In this case, I am calling the same function 10 times. Each task does the following:

  • prints a message saying for how long it plans to sleep
  • sleeps for that amount of time
  • prints a message saying it is complete
use std::thread::sleep;
use std::time::Duration;
use tokio::task;
 * Grab a random number, say that you're going to sleep
 * for that number of ms, and say when the sleep is complete
async fn random_print(num: i32) {
    let r = rand::random::<u64>() % 500u64;
    println!("msg{} will sleep for {}ms", num, r);
    println!("msg{} complete", num);
 * mark main() as the main function to use with the tokio runtime.
 * It's normally ok to just use #[tokio::main], but here, I am
 * explicitly saying I want to configure the runtime to use
 * multiple threads, and I want 8 threads configured.
#[tokio::main(flavor = "multi_thread", worker_threads = 8)]
async fn main() {
    /* create a vector for the join handles. This is a nice to have, but not required */
    let mut handles = vec![];
    /* let's start a function 10 times */
    for j in 0..10 {
        /* start a task */
        let handle = task::spawn(random_print(j));
         * save the handle for later use. This handle can be used
         * to check if the task is complete later.
     * the next loop is useful if you want to explicitly wait for all tasks to complete.
     * A more complex implementation might require that you only wait for certain
     * tasks to complete
    for handle in handles {
        let _ = handle.await;
Here’s some sample output. If you run this code, your output will almost certainly be different, but similar.
msg0 will sleep for 190ms
msg1 will sleep for 458ms
msg2 will sleep for 260ms
msg3 will sleep for 345ms
msg4 will sleep for 321ms
msg5 will sleep for 109ms
msg6 will sleep for 4ms
msg7 will sleep for 188ms
msg6 complete
msg8 will sleep for 155ms
msg5 complete
msg9 will sleep for 379ms
msg8 complete
msg7 complete
msg0 complete
msg2 complete
msg4 complete
msg3 complete
msg1 complete
msg9 complete

First, you need to start the Tokio Runtime. There are several ways of doing this, but by far the easiest is to just use a macro attached to fn main() and tell Tokio to start automatically.


fn main() {


async fn main() {

Now, when your main function starts, the Tokio runtime will start as well. Note I used the async keyword on the main function. As mentioned above, you need to understand async/await for this tutorial to make sense, so please ensure you are familiar with these concepts.

In my example, I used a slightly more configurable version of this macro when I wrote:

#[tokio::main(flavor = "multi_thread", worker_threads = 8)]

Tokio can schedule your tasks in several different ways. I chose the “multi_thread” scheduler, and I asked for Tokio to use 8 threads. This is overkill for this example, but it is included to show some of the available configuration options.

It is also possible to start the runtime manually, as I will show later.

The important line in the code is

let handle = task::spawn(random_print(j));

This is called 10 times in a loop. spawn() creates a Tokio task and the code to run in this case is the async function random_print().

Tokio will move the task to the background to some thread, and when possible it will run that task concurrently with any other tasks allocated to the thread. You don’t need to pick the thread, or decide when the task runs. Tokio takes care of everything.

Finishing task processing

It is important to know when a task completes. The last thing to you want is for your application to exit while a background task is still completing. task::spawn() returns a JoinHandle that can be used to communicate with the running task. Note that in my second loop, I call JoinHandle.await. This ensures all tasks are completed before the application exits.

Starting Tokio from a non-main functions

The example above is the typical scenario covered in most examples. However it is possible to start multiple Tokio runtimes, and to also start those runtimes in a non-main function. See the code below:

use std::thread::sleep;
use std::time::Duration;
use tokio::runtime;
async fn random_print(num: i32) {
    let r = rand::random::<u64>() % 500u64;
    println!("msg{} will sleep for {}ms", num, r);
    println!("msg{} complete", num);
fn main() {
fn not_a_main_fn() {
    let rt = runtime::Builder::new_multi_thread()
    for j in 0 .. 10 {
     * I'm being lazy here, and just delaying to let all tasks complete.
     * Using JoinHandle.await is much better. Also, comment out this line
     * and you will notice the program most likely ends before all 10 tasks
     * complete correctly!!! This is why JoinHandle.await is important!

The code is similar to the original example but not the same. Here, main() is not an async function, and all it’s doing is calling

fn not_a_main_fn()

not_a_main_fn() is responsible for starting a Tokio runtime manually, configuring it, and then using it. Notice, for instance, that task::spawn() has been replaced with rt.spawn(), meaning that the newly spawned task will run on the runtime referenced by “rt”. Note also that the


macro is not used at all.

Lastly, a sleep statement was included here instead of cleanly waiting for every task to complete. This version of the code will typically take around 5 seconds to execute which is wasteful. But commenting out the sleep statement will most likely result in the application not working correctly. My sample output when commenting out the sleep statement is shown below:

msg1 will sleep for 243ms
msg0 will sleep for 207ms
msg0 complete
msg1 complete

That’s it. 10 tasks were created but only 2 ran. This is because the main application exited before the tasks completed. This is why it is important to collect JoinHandles from tasks and ensure tasks exit cleanly.


Tokio is an async runtime for Rust. It is very easy to use in its default configuration, and not much more complex when configuring it manually. With minimal effort, you can schedule multiple tasks on multiple threads, without the effort of implementing any low level details.

The End

The Bolivian Visa Extension Nightmare Ends

This is a follow up to a post I made earlier about my bad experience getting a visa extension in Bolivia. You can read about that here:

The week started badly, with a four and a half hour wait at migrations in Santa Cruz, but with what seemed like a happy ending. There was one oddity, though I didn’t think too much about it at the time – they took away my passport to get the visa extension. I’m from South Africa so we qualify for visa-on-arrival. Visas, extensions, it’s all supposed to happen over-the-counter. Still, I was given an official document stating I need to return on Thursday to collect my passport. It wasn’t ideal, but not a huge problem in the slightest.

Fast forward to Thursday. I showed up a little earlier at migrations than Monday to avoid the excessive wait times and it worked! After roughly and hour my name was called. I approached the counter, handed over my official pick-up slip and … no passport. The extension hadn’t been processed yet. After some asking around an official, Juan (not his real name), told us the best would be to show up early the next day. 8:30am was the preferred time. This was downright inconvenient, but hey, I showed up early on Thursday, and perhaps it was a little too early. Maybe my visa extension would be processed later in the day.

Fast forward to Friday morning. We were at migrations bright and early and … no passport. It was getting harder to remain calm especially since, in less than 24 hours, we were planning on leaving the city and we had no place to stay in Santa Cruz. Our next accommodation was in Cochabamba which I’d booked shortly after I got the pickup slip saying my passport would be ready on Thursday. Naturally, we were less than excited when the official statement from Juan was to wait and see.

So we waited. There was nothing to see. After asking a few more times, it turned out the guy who processes visas wasn’t at the office yet. And my visa processing hadn’t even started. An hour later, he still didn’t show up and Ana told Juan, for maybe the fifth time, that if we do not get the passport today we will have no place to stay. The implication was their incompetence would end up being very expensive for us. Finally, thankfully, it clicked. It’s like a switch was flipped in the man’s brain and he suddenly seemed to understand that we weren’t just impatient and petty, we had a real problem. He told us to return after 1pm and he would try getting our visa in the meantime. We were cutting this really close.

Fast forward to 1:10pm. We show up and Juan tells us my passport is being processed now. The signs were good. Someone even came out of a back room and asked a few questions like when we would be leaving the country – signs that things were heading in the right direction. By 2:10pm, with no other word from anyone, our enthusiasm waned significantly. We were joined by perhaps 7 other people, all with the same problem. We were just fortunate enough to be the first ones to arrive, so we were at the front of the queue. An older lady from the US, and old couple from the US, a German lady and what sounded like her French friend, and several other people waited hopelessly, with the older American lady clearly exasperated. “It’s unbelievable”, she kept saying. She couldn’t understand how, despite her having all the required documents, and having jumped through every arbitrary bureaucratic hoop, he was still waiting in line after 2 hours. I don’t think she found comfort when I told her I was there for the 4th time that week, spread out over three days, and I was on maybe hour 8 or 9 at the time. Some people just gave up and left but that was not an option for us.

Finally, Juan told us that my application was being “analysed” (scrutinized) for some unspecified reason, but to wait a little longer because we would definitely get the passport back today. Perhaps 30 minutes later Juan returned with the passport, handed it to another official who made me sign a few forms and my “visa extension” was ready.

It wasn’t a visa extension, it was a completely different visa. Juan said the original visa I obtained in Salta, Argentina, from the Bolivian consulate was in a different format (or something) from the visas they issue within the country, so they needed to issue me a whole new visa, even though it was processed and charged as a visa extension. But whatever, I had what I needed, and that rounded off a miserable week.

The level of inefficiency is simply astounding. Bolivia is a beautiful country but quite honestly, once my current visa expires, I will try not to return any time soon. The stress, uncertainty, bad information, delays, and just time wasted makes a return not worth the effort. Perhaps my mind will change in the next month, but for now I am a very disgruntled tourist.

A small silver lining

Along with getting a visa extension, I needed an extension for my motorbike. I rode to aduanas (customs) on Thursday, and explained I needed the extension despite not having my passport, which was at migrations. I took the collection slip issued by migrations as proof.

The process was refreshingly simple and efficient. We waited for perhaps 5 minutes before being processed. At the counter we supplied the relevant documentation, and my South African national ID card, along with the document from migrations that contained my passport number, were sufficient. About 10 minutes later a lady came outside to inspect my bike, a process that took less than 5 minutes. A few minutes later and I was issued a 60 day bike extension.

Quick, simple, efficient. The way it should be.

The Bolivian Visa Extension Nightmare

I almost have my visa extension. I will get my passport back in 3 days; everything went well, relatively speaking.

I’m going to split this post up into 2 main parts. The first is for people who want to know what to do. It will just state the facts with little else. Part 2 will focus on my less than stellar experience.

Part 1 – What You Need To Know

Preface – Read this first!!!

As noted in my other posts, the Bolivian government does not supply accurate information. The steps required to perform a visa extension are relatively straightforward, but I did not find a single source of information that accurately details what is required. So I am detailing it here.

This information is correct as of 17 January 2022. I obtained my visa extension for 30 days at a migrations office in Santa Cruz De La Sierra. Additionally, note that I am from South Africa, which is classified as a Group 2 country by Bolivia, and as such we qualify for visa-on-arrival for which we do not pay. If you are from, for instance The United States, you are from a Group 3 country and while the general process will be similar, expect differences, especially in terms of cost. Ditto for Group 1 countries.

The documentation problem

Firstly, if you dig deep enough on the government website, or even look at the sign on the wall at migrations, you will note that the information supplied is to obtain a visa for entering the country. That information lists the required documentation for a new visa only, not for a visa extension!!!

Where to go

On the official government website, various migration centres are listed for Santa Cruz. For a visa extension, you need to go to the migrations office in centro, at the corner of Calle Sucre and Calle Potosi.

Other visa offices, like the one at Ventura Mall do not process visas for foreigners. I know because I tried first at Ventura Mall and was turned away.

When to go

Go within 5 days of your visa expiring. On a successful application, your passport will be taken away and you will need to return to collect it 3 days later, so factor that into your travel plans. The extension is valid from the date of allocation. So if you apply, say, on day 14 of your trip, and your visa is allocated on day 15, you will have an additional 30 days from day 15 i.e. you won’t get 60 days, you’ll get 45 days in Bolivia (in this example).

Going to the migrations office earlier in the day is better. They open at 8am. I arrived around 10am on a Monday and I had a 4 and a half hour wait.

Also, and take this with a pinch of salt because I do not know this for certain, I read (on a Google Maps review from 2 years ago) that visa processing stops at 12:30pm. I don’t know if this means they stop allowing people into the building, or even if that information is now outdated. Be aware regardless.

What you need

  • A photocopy of your passport
  • A photocopy of your existing visa from your passport
  • A photocopy of the page in your passport that shows the entry stamp you received when entering Bolivia
  • A photocopy of the document you received from migrations when you entered the country (for me, it’s a small white form, about half a page long, that’s filled in by hand but that has an official migrations stamp)
  • A photocopy showing where you will be staying – I use Airbnb so I selected my existing reservation and selected the option “Get a copy for visa purposes”
  • A photocopy of your exit plans. This could be a plane ticket, or bus ticket, etc. In my case, I am traveling with my own vehicle so I needed a copy of the form I received from aduanas (customs) when I entered the country
  • 2 passport photos. My photos were in colour. I do not know if black and white photos are acceptable
  • Cash or a card for payment. For me, the cost was 592.50 Bolivianos. I have no idea why, since I am from a Group 2 country and should not need to pay, but my Spanish isn’t good enough to question this. So I paid.

What I did not need

  • I did not need to fill in any form online or download a form and fill it in myself. When applying, the person processing your application will request photocopies of the data and fill in the form for themselves on the computer.
  • I did not need a copy of my bank statements (i.e. proof of financial solvency)
  • I did not need a copy of my yellow fever vaccination card
  • I did not need a copy of my itinerary
  • I did not need any proof of medical insurance
  • I did not need a vaccine certificate, or anything Covid related

Other things to carry

Coins, preferably in Bs 1.00 or Bs 0.50 denominations. At the Santa Cruz office, there was a lady who did printing and made photocopies in the same room where your application is processed. The cost is Bs 0.50 for a photocopy, and Bs. 1.50 for a colour printout.

For printouts, the lady has a Whatsapp number. You send her the documents via Whatsapp and she prints them for you.

As a bonus, she also sells snacks.

People were going to her to get photocopies as their applications were being processed. So if you need a copy of something, having a few extra coins will really save you lots of time and effort. You will need her services, even if you have your own copies, as I will explain later.

Lastly, if you’re going to be waiting long, you may want to use the bathroom. When I was there, the bathroom didn’t have lights. Most people were using the torch on their phones. Hopefully this was just a one-off problem and not a regular occurrence.

The Process

Please note once again that I did this at the migrations office in centro, Santa Cruz. If you apply for the visa elsewhere, your mileage will likely vary.

  • When you enter migrations, you need to tell the security guard you need a visa extension. He will check to ensure you have the correct documents. In my case, he pointed to the wall and asked if I had all the relevant documentation. The information on the wall is not for a visa extension!!! Regardless, that’s the official list, so say yes. The list will say, for instance, that you need to fill in a form online, and that you need a copy of your yellow fever vaccine card. These are the requirements for a new application! There was no list of requirements for the extension. So nod, say you have everything, do whatever, so long as you get to the next step which is …
  • Ensure he registers you. He will take your passport and enter your details into the computer (and return your passport immediately). You are now in the system. He should direct you to the third floor. My experience was different. You can read about it in Part 2.
  • The third floor is the waiting room where you will be processed. A computer calls out the name of the next person and where they need to go. You have no number. There’s no list of who’s going to be processed next, or where you’re positioned in the queue.
  • Now you wait. Maybe you get lucky and the wait isn’t long. I waited four and a half hours with no indication whatsoever my turn was coming up. Nobody was willing to assist. I was one of many people in the same unfortunate situation. I advise taking something to keep yourself entertained.
  • Eventually you will be called. Supply the information requested of you, and you will be asked to pay. I paid by card. This part of this process was very smooth and everyone was very friendly and patient, especially considering my almost non-existent command of Spanish.
  • It will be necessary to visit the copy lady. For instance you will need a copy of your application. Migrations will print out the application, but you will need to make a photocopy of the printout at your own expense. Also, if you pay by card, you will need a copy of the receipt. So carry carry Bs 1.00 and Bs 0.50 coins.
  • If all goes well, migrations will keep your passport and give you a form with a date when your passport, complete with visa extension, must be collected. Do not lose the form!!!! Take a photo of it to be safe.
  • You’re done!

Part 2 – The Story

(This was written on my phone while waiting at the visa office)

I’m now 10 minutes shy of being in the visa queue for 4 hours. I truly despise Bolivian government inefficiency.

I need a visa extension. But much like my experience getting the visa, which you can read about at, the process has not been at all smooth so far. And once again, it boils down to lack of information.

There’s no clear guidelines that explain the process: things like where to go, what documents are required, and how much I need to pay, if anything. A few sentences exist on the government site, but they cover getting the visa. And it is mentioned that the visa may be extended, but no details are specified for the actual extension. Which is why I once again relied on years old blog posts that, aside from being Pre- Covid, I suspect may now be incorrect. The simple, near pain free experience of other travelers is certainly not echoed in my experience.

My process so far was simple (he said sarcastically). I stood in line to talk to the guard at reception. 10 minutes later, I explained I’m from South Africa and I need a visa extension. He flipped through my passport and told me I had no stamp showing I entered Bolivia. I pointed out the stamp, and he, almost grudgingly it seemed, sent me to the first floor. Here, I had no idea where to go, so I asked, and a busy lady told me to head to the third floor.

Two flights of stairs later found me in a room full of seated people, with a row of counters at the front and off to one side. A lady manning a photocopier and printer occupied the far corner of the room. Periodically a computer system would call out a name and counter number, and that person would head to the appropriate counter to be processed.

But how would the computer know my name? I asked and a lady told me to wait with the rest of the crowd. As everyone else was busy, I asked the photocopy lady and she told me to ask at one of the counters. With no other options, I interrupted one of the workers to ask if I was in the right place, and she said my name would be called because the guard downstairs registered me on the system. Except he didn’t do that.

Three flights of stairs later found me talking to the guard at the entrance. I told him I need an extension and I need to be registered on the computer. So he lackadaisically checked I had the required paperwork to proceed (against the wrong checklist), but nevertheless registered me and up I went again, hoping I was in the right place.

That was over 4 hours ago now. There are no queue numbers. I’m just sitting and waiting, with no way of knowing how long the delay will be. Others whom I can only assume are here for the same reason seem annoyed, but also resigned to waiting patiently, as though they’ve been through this massive waste of time before. I’m the newbie it seems.

At first I panicked and thought I would run out of time, and hurriedly tried to organise myself, using numerous opportunities to make copies of just about everything I thought may be needed. But I’ve given up caring now. I just want …

Literally as I was halfway through typing that sentence my name was called. Actually obtaining the visa extension was a relatively smooth process, as I detailed in Part 1. The staff were efficient, patient, and friendly. Processing was smooth. Obtaining the extension, from the time my name was called, to the time I left was perhaps 20 minutes.

The 4.5 hour wait with no feedback was unacceptable, as was the lack of documentation requirements. Unfortunately that appears to be a typical part of Bolivian life. The attitude is very much one of “that’s just the way it is”. But if you magically happen to have everything you need, things will go smoothly. Eventually.

I still hate Bolivian government bureaucracy with a passion.

13 Lessons I Learned Road-Tripping Across Bolivia

I travel by motorbike, and I love it. I find nothing more freeing than riding over vast distances while soaking up everything the land has to offer: Mountain passes, dirt roads, freeways, small towns, roadside cafes, suspicious hotels, beautiful sunsets, and everything in-between.

For almost a month now, that land has been Bolivia. After almost two years effectively trapped in Argentina due to Covid restrictions, I’m finally on the move again and Bolivia is, without a doubt, the most interesting, and most difficult country I’ve travelled through thus far. Here’s what I’ve learned, both good and bad, and in no particular order:

Bolivian Time

Punctuality is more optional than required. I’ve been on a tours that started, eventually. I’ve been on time for appointments and was frustrated by delays. Cashiers seem unnecessarily slow. The urgent documents I need to be processed will be processed, but there’s no hurry.

And nobody seems to mind. Traveling through Bolivia requires a mindset shift. Relax. There’s no rush. Or as the locals say, “tranquilo”. Having your expectations governed by first world concepts of punctuality will frustrate you immensely. Things are done differently here, and at a much slower pace. Take a deep breath and go with the flow. It’s not wrong, just different. Tranquilo.

Government Bureaucracy

The government loves paperwork. And lots of it. Everything submitted online needs a photocopy or three. I needed close to 60 pages of documentation to cross the border, and was required to prove things like financial solvency, and provide a detailed travel itinerary in order to get a visa. A myriad of checks were performed before I could enter the country, and the process was downright painful. Quite literally too. The 5 hour border crossing left me sun burnt. I documented the ordeal here

Prior to this, I considered a 1 hour crossing long.

I use a special document to get fuel. Visa extensions must be obtained every 30 days, but at most twice. There always seems to be a complex set of undocumented rules that need to be followed strictly. Just yesterday I tried applying for a visa extension at a valid migrations office, only to be told my request can only be serviced at a different branch on the other side of town. Navigating the bureaucracy is maddening, especially when it cuts into the very limited time allocated to you for your stay in the country.

Travel Is Slooooow

My first big trip in the country was from Villazon, near the Argentina border, to Tarija. Google estimated the distance as 194km, but with a travel time of over 4 hours. I scoffed at the idea. After all, I would be traveling through national freeways. An average speed of under 50km/h seemed ridiculous, and Google was of course being overly cautious.

Surprisingly, Google was spot on, and I was scheduled to arrive in 4 hours. The trip ended up taking closer to 6.5 hours, largely because for the last 50km, I chose to ignore Google’s advice and follow a dirt path over a mountain in the rain. While memorable and a story worthy of being considered another notch on my travel belt, the experience in the moment was no fun at all.

Travel in Bolivia is slow. Very slow. Motor ways are winding single lane mountain roads, often climbing or descending steeply. So it is commonplace to find yourself stuck behind a large bus or truck, or even a little family car travelling at 20km/h on a national freeway.

The road quality varies considerably. Route 5 (Ruta 5) near Uyuni in the south is just a massive dirt road with large muddy patches when rivers or lakes overflow. The road between Villazon and Tarija is a well maintained, but extremely winding dirt road through the mountains for about 70km. The roads between Tarija and Sucre were amazingly well maintained. But the journey between Sucre and Santa Cruz saw road conditions vary wildly, starting with meticulously well maintained tar roads, followed by a large number of mudslides that nobody bothered cleaning up, to roads so poorly maintained it was more pothole than freeway.

Combined with very conservative speed limits, expect a 500km journey to take north of 10 hours. I’ve learned to trust Google time estimates in Bolivia more than any other country.

The Food Is Great

The combination of excellent quality ingredients and a superb spice palette make Bolivian food some of the best I’ve tasted. The variety of fresh, yet cheap, fruit and vegetables amazes me. Meat is the order of the day and dominates most menus, though trout and other fish offerings are just spectacular in every town.

Vegetarians, unfortunately, are not well catered to, especially outside major cities.

From a taste and quality perspective, Bolivian food is fast becoming my favourite in the region!

Amazing Scenery

One of the highlights of road tripping though Bolivia is the spectacular natural landscape that’s just about everywhere. Travel on any national freeway for a few minutes and you’re likely to find yourself enveloped in the natural beauty of the country.

From dusty mountains in the south, to almost other-worldly landscapes in the middle of the country, to rolling green hills leading to the jungles in the east, Bolivia is a natural wonder. And there’s no need to look far for any of it; amazing views can be found almost everywhere.

Landscapes aside, city centres are often sights to behold, with colonial influences evident in picturesque streets. Walking through Potosi, Tarija, and Sucre feels like stepping into the past in a way. But the illusion is quickly dispelled once you leave the city centre and are faced with dilapidated buildings and poorly maintained streets. Still, it’s worth enjoying the good parts.

It is Safer Than Expected

I wouldn’t go as far as to claim Bolivia is safe, but it is certainly far safer than I expected. Numerous people warned me about the dangers of this country, from petty theft, to muggings, to streets I should avoid because of all the horrible things that would happen to me if I dared walk on them.

Perhaps I’ve been unusually fortunate, but my experience of Bolivia has been extremely positive. I don’t feel as safe here as I do in, say, Argentina, but neither am I in constant fear for my life or belongings. By taking regular common-sense precautions, I doubt many travelers will experience problems.

Fuel Is Hard To Find At Times

This is a tough one to deal with. Fuel stations are often few and far between, and since many are not listed on Google maps for instance, planning long journeys can be tricky. This is very unlike Argentina for instance, where it seems a fuel station can be found every few blocks in a big city, and stations are relatively commonplace on major routes.

By contrast, I’ve often found myself scanning the map for the next fuel station here in Bolivia, and keeping an eye out for businesses and even houses that offer fuel in small towns. Leaving Sucre towards Samaipata, for instance, there are no (or at least no easy-to-find) fuel stations for a few towns.

This isn’t really a problem when traveling by car, since the fuel range on a car is usually sufficient to bridge the gap between fuel stops. But traveling by bike, where the fuel range is effectively halved due to the small tank size, can be a concern. Thankfully I haven’t had a problem so far. But I fill up more often than I need to, when the opportunity arises.

Another oddity is the two-tier fuel price in the country. Locals pay one rate (around 3.50 Bolivianos per litre), and foreigners pay a different rate (around 8.50 Bolivianos per litre). I suspect the very cheap local fuel rate makes owning a 4×4 in this country an affordable prospect. And 4x4s are extremely common here.

Getting Information Is Tricky

It’s near impossible getting accurate information here. The government website is an indecipherable maze of disconnected links. I’ve largely relied on things like blog posts for information, with varying levels of success.

Bolivian embassies often supply conflicting, and often outright wrong information.

Much of the country’s information cannot be found online easily, or accurately. Street view, for instance, is not available in many parts of the country. Many businesses either do no have webpages, or their pages are very out of date. In many cases, things like a web search will not yield useful results. As mentioned above, fuel stations are hard to find. And only a small fraction of restaurants, supermarkets, and other useful places can be found easily online.

This makes modern travel difficult. Not impossible by any stretch of the imagination, but far more challenging than traveling in many other countries. But when in doubt, just ask a local. Bolivians are a friendly lot, and very helpful in my experience!

Traffic Stops For Nobody

See that pedestrian crossing? Yeah, nobody cares about it. Cars will not stop. I’ve joked that pedestrians in this country have great cardio because life as a pedestrian involves looking for a gap in traffic and running when you find one.

On a different note, driving on motor ways is often a game of life or death. I’ve almost been killed at least three times in the last three weeks. I’ve encountered cars and buses driving on the wrong side of the road, even around blind corners. Cars pull out into traffic without looking, while traveling at dangerously low speeds (for motor ways). One of the pieces of advice I was given before arriving here is don’t drive at night! From what I’ve seen so far, it’s great advice!

People Are Small

I’m around 1.89-ish metres (6 feet) tall. I’ve hit my head on door frames here too many times. I often need to duck to avoid hitting my head on awnings in front of shops. Right now I need a pair of size 12 or 13 shoes, yet all the shops I’ve visited go as high as size 11. These are not problems I was expecting.

People around these parts are smaller, and larger people find ourselves a little out of place at times.

Internet Is Better Than Expected

I purchased an Entel SIM card when I entered the country. Topping up is easy, and coverage is great. WiFi has not been a problem so far, and while speeds are not as spectacular as they are in, say, Buenos Aires, I have not yet encountered any serious Internet connectivity issues. Of course I doubt my experiences would be this positive if I frequented the more rural parts of the country, but in general, I’ve found the internet connectivity in the country to be surprisingly good!

I require good internet for my work, and so far I haven’t encountered any serious problems.

Extreme Altitude And Weather

Santa Cruz is at 400m above sea level, hot, and uncomfortably humid. So much so that running even 2 blocks will have me dripping with sweat.

Potosi is around 3800m above sea level, with temperatures in the mid 20s, perfect for exercise. But the town is build on hills and the altitude meant I was out of breath each time I walked uphill. I couldn’t run there.

I ran in Sucre. That entire city is just steep hills, so while the altitude and weather were pleasant enough, going for a run was really tough.

Altitudes and temperatures in this country vary wildly, even in a single season. In Potosi and Uyuni, I could see mountains covered in snow in the middle of summer. In Santa Cruz, the heat is so extreme I feel like melting.

While I knew Bolivia is a mountainous country, I wasn’t expecting the variety of altitudes and temperatures to affect me this much. I would dread going on a hike in Santa Cruz, or in Potosi, but for very different reasons.

Cash Is King

I have a Visa credit card which I have always used successfully in other countries. Here, things are different. I’ve successfully made credit card purchases, but around 50% of transactions have failed. The failures have been the type where my bank is notified of the transaction so the money is reserved on my credit card, but the transaction never completes successfully.

After about a week, I get my money back on my credit card, but the entire process is extremely inconvenient. Also, people around here just prefer cash. I asked at cellphone stores, restaurants, even when getting my bike serviced. It’s not that card machines are unavailable, it’s just that cash is preferred. This can get tricky with large payments (like servicing a motorbike)

On a positive note, ATMs seem to be plentiful in larger towns and cities, and transaction fees are low. But don’t count on finding an ATM in smaller towns, or assume card facilities exist there either. Having a few hundred Bolivianos in your pocket is likely to save you from major problems.

That’s my experience so far. Hopefully it’s been of some help.

How to Cross Into Bolivia By Land Border


I am a South African riding my motorcycle in South America for the last few years. I have been in Argentina since before the Covid lockdowns and since most land borders opened on 1 November 2021, I decided to take the opportunity to head to Chile. Unfortunately due to the new Omicron variant ravaging the population, Chile closed their borders on short notice and so I decided to head to Bolivia. This post describes how I did it. It was neither fun, nor easy.

For reference, I crossed from Argentina to Bolivia on 22 December 2021. For about 5 days prior, I was in Salta, Argentina. The aim was to cross via La Quiaca, Argentina, to Villazon, Bolivia. Now, let’s get started.

The Madness

Finding information on getting into Bolivia was not easy. My primary source of information was blog posts because there appeared to be no clear information on the government website.

When Chile closed their borders, we immediately contacted the Bolivian embassy to find out if we could cross by land. The answer was yes, but also that this was only possible via La Quiaca. We took their word on this – after all they are the Bolivian embassy – but this information was apparently incorrect as we would later discover. However, for this reason, we headed to La Quiaca.

South Africa is meant to be a visa on arrival country, so it seemed safe to assume I could simply show up at the border and get my visa there. But La Quiaca is a smaller border crossing and I wanted to make sure I wouldn’t run into any problems. So while in Salta, I thought I would ask the embassy. After all, it should only take 5 minutes, right?

We left Salta a day and a half later.

We entered the embassy on Monday morning around 9am and asked if we could, indeed, obtain a visa at the border. Their systems were down across the country, but the lady assured me that I would need to pay $160 (this is incorrect) because South Africa is from a Group 3 country (also incorrect). She said she would like to confirm this (thankfully), but we would need to return around 1pm. We were also told that while we could leave via La Quiaca, we would be unable to return via that border crossing (yet more incorrect information).

At 1pm their systems were still down, but she now knew for certain that South Africa was a Group 2 country and no payment would be required for the visa. However, she had no idea if it would be possible to process visas for visa-on-arrival at the La Quiaca border, or at the embassy there. Since La Quiaca was 6 hours away, I hated the thought of turning a 6 hour trip into an 18 hour trip due to me having to return to Salta to fix this problem, so I stayed, hoping to obtain my visa in Salta.

But the visa printing machine was broken, and a technician would only arrive to fix it after hours on Monday. Even then, there was no guarantee it would be fixed. We were asked to return at midday on Tuesday, and I found a hotel for the night.

On a positive note however, we met two Israeli girls at the embassy who were struggling with the same problem. From them, I learned I needed to fill in a form online. I had a paper version of this form which I thought I needed to complete in pen, and submit at the embassy, but I was wrong. More on this later.

At midday Tuesday, we were told to return around 15:30, technically after hours, because they were busy. At 15:30, my documents were processed and I was issued a visa. The process took almost 2 hours. On Wednesday we rode to the La Quiaca border, arriving around midday. After 5 hours of processing, while standing in direct sunlight for the most part, we were finally allowed into Bolivia.

The process was awful from start to finish. I have read other blog posts where people were let through in 5 minutes at airports. Our experience was completely different.

I will list the steps below, briefly, then cover each in detail.

The Steps

  1. Figure out your country grouping. If you are from a group 1 country, you can probably get in with no complex steps, so you can pretty much stop reading here. But more on this later. For everyone else …
  2. Fill in a form online. You will be taking this form to the embassy to get a visa
  3. Within 48 hours of arriving, you will need to complete an online declaration. This is a Covid measure
  4. You will need a valid PCR test within 72 hours of arriving
  5. Have proof of Vaccination, preferably with a QR code.
  6. You will require vehicle insurance (if travelling with your own vehicle), and medical insurance covering Covid
  7. Optional but highly recommended: Speak fluent Spanish, or have someone in your group who can speak fluent Spanish. I had Ana. We are in Bolivia now because of her.

Sounds straightforward right? It’s not. Let’s cover things in more detail.

Country Groupings

Bolivia classifies travellers by country. There are 3 country groups: Group 1, Group 2, and Group 3.

Group 1 countries appear to be for neighbours. People from these countries, like Argentina, do not even need a passport to enter. Their national ID card is sufficient. If you are from a Group 1 country, chances are you can enter with minimal difficulty. Just ensure you have 2 photocopies of all documents required at the border (e.g. for the PCR test, insurance, etc).

Group 2 countries are for people who need a visa, but where no payment is required. South Africa is a group 2 country, and South Africans qualify for visa on arrival. This does not appear to be a problem at airports, but at land borders, nobody seems to know whether it can be done, even when asking at embassies. So I opted for getting the visa beforehand at the embassy.

Group 3 countries are everyone else, eg. the US, many countries from Europe, Israel, etc. Travellers from these countries need a visa, and as of the time of our entering (December 22, 2021), they need to pay $160. According to the embassy, the wait time for the visa is 48 hours to 3 weeks. The Israeli girls we met at the embassy insisted their friends got visas in Mendoza on the same day and paid just $30, but the lady working at the embassy bluntly stated they were wrong, and what they claimed was impossible. Make of that what you will.

Visa Durations

The homework I had done stated that the visa duration is 90 days, like most other South American countries that South Africans may enter. This is only technically correct.

Foreigners may stay in Bolivia for a maximum of 90 days per year, but visas are allocated for at most 30 days at a time. You may go to migrations offices in certain cities and obtain a 30 day extension at most twice, giving you a total of 90 days. You cannot obtain a 90 day visa as a regular tourist, but you can get a 30 day visa and 2 x 30 day extensions.

Incorrect information

As mentioned above, we were told by the Bolivian Embassy (in Buenos Aires) that only La Quiaca was opened. This is incorrect. Apparently all land borders were open. One of the border agents even asked why we were crossing at La Quiaca to go to Tarija when a different border crossing was so much closer to the town.

We were told by the Bolivian embassy in Salta that we could leave only via La Quiaca. This is also incorrect. Apparently we can leave and enter from any crossing.

We were initially told by the Bolivian embassy in Salta we needed $160 to cross because South Africa is a Group 3 country. South Africa is a Group 2 country and no payment is required. Admittedly, the Salta embassy later corrected this.

But please note that all this information was obtained from embassies. From official sources. And all the information was incorrect. So do your own homework, call around, and do not trust a single source of information.

The Online Form

In order to apply for a Visa, you need to fill in an online form. This form can be found at the following link:

I got to the link by searching for “visa application form Bolivia” on Google, and the first link was for “Formulario Solicitud de Visa”

This link is valid as of the time of writing this blog post i.e. 6 January 2022.

This is a multi step process and for the most part, the process is very straight forward. Enter your name, country of residence, reason for entering, etc. The final step is where it gets tricky.

You will need to supply:

  1. Proof of financial solvency. For this, I got bank statements online. They were sufficient
  2. An itinerary of your stay – I opened up a word processor and wrote out what I would do in the country e.g.
    1. Enter country on 22 December
    2. Spend 5 days in Tarija
    3. Spend 5 days in Santa Cruz
    4. etc
  3. A recent photo of yourself – it needs to be a certain size so a selfie probably won’t do. See below.
  4. I needed proof of where I would be staying. I booked accommodation via AirBnB, so I just got a copy of the booking from them
  5. Proof I was vaccinated against yellow fever. Thankfully I am and I have a copy of my yellow fever vaccination card.
  6. A copy of the application. This is tricky because the last step of completing the application is submitting a copy of the application that you’re trying to complete. It’s a catch-22. However, on the page where you submit your documents, there’s a link that lets you view your application. I opened the link in a new browser tab and that link was a PDF copy of all the information I had entered till that point. I saved a copy of that PDF, then submitted that copy as the last step. It was the correct thing to do. Note that I also signed the PDF before submitting, but that does not seem to be required. Note also that at this step of the process, the form you submit will not have a reference number at the top.

Now here’s the next, really tricky bit. There is a strict 500KB limit on all document submissions, and a 150KB limit for the passport photo.

Despite having all the information, I needed to sit with an image editor and rescale all my photos (like the yellow fever card and passport photo) to meet the document size limits. It was exceptionally frustrating. You may think you can obtain a recent photo of yourself by taking a selfie. Think again. A selfie is likely to be several megabytes large. You will first need to crop the photo to be square, then reduce the size to be under 150KB.

Once all documents have been submitted online, you will receive a PDF copy of the application, but this copy will have a reference number at the top eg. RREE-VC-738473. The number is very important! If you only have RREE-VC-, it means your document has not been submitted, or in other words, the Bolivian embassy is unaware of your application! You need this number!!!

Make Photocopies

You need three (that’s right, three) copies of almost EVERYTHING you submitted, including three copies of your application that has your application code (eg. RREE-VC-738473), as well as 3 copies of your passport. I was not asked to submit a copy of my passport, but I still needed 3 copies.

One copy of every document, including a copy of the application was required at the embassy. An additional 2 copies were required at the border. One copy of all documents for both Bolivia and Argentina was required by the Argentinian authorities, and one copy of all documents for both Argentina and Bolivia was required by the Bolivian Authorities.

I needed around 40 pages of photocopies at the border, and around an additional 20 pages at the embassy. I estimate I needed between 50-60 pages of documents to cross the border at La Quiaca. These documents were (I will try and list everything I can remember):

  1. The application form (with the reference number)
  2. My passport
  3. My exit declaration form for leaving Argentina (Only needed at the border, so 2 copies)
  4. My entry declaration form for entering Bolivia (Only needed at the border, so 2 copies)
  5. My itinerary
  6. Proof of financial solvency (required for getting the visa only, so one copy of each page)
  7. Details of accommodation
  8. Yellow fever vaccination card
  9. PCR Test Results (required at the border only, so I needed 2 copies)
  10. Proof of vaccination. I used my vaccine certificate with a QR code (only needed at the border, so 2 copies)
  11. Proof of medical insurance, with Covid Cover (only needed at the border, so 2 copies required)

Now, of course you may be looking at that list and thinking I’m crazy. After all, you submitted a lot of this information online, so why would you need copies? Or perhaps you’re thinking you have a digital copy on your phone and you can just show it to the border guards. After all, that’s what I did when I visited Uruguay not too long ago.

But this is the La Quiaca crossing into Bolivia, and holy crap do they love processing paper. If you do not have paper copies, you will be asked to get them. The staff are very polite and will instruct you to head into town (La Quiaca) and return when you have the copies. I was missing 2 copies of my passport, and I was told to do exactly this, despite having a digital copy on my phone, and my actual passport in my hand. Thankfully I had extra copies in a different bag.

Make photocopies of EVERYTHING

Regular Stuff

  1. Ensure you do a PCR test. That’s pretty standard for travelling these days so I will not go into further detail.
  2. Complete a declaration for exiting Argentina (assuming that’s what you’re doing). The link is: . Note that this is a 2 step process. In step 1 you enter your email address. You will then receive an email with a link to complete step 2.
  3. Complete the declaration for entering Bolivia. You can find it here:
  4. Ensure you have medical insurance
  5. Ensure you have copies of your Covid vaccine certificate
  6. I needed copies of my yellow fever vaccinations when applying for the visa, but not at the border. Your mileage may vary.

And of course, make copies of all these documents; two copies of each, but preferably three!

If Entering With A Vehicle

This was surprisingly easy overall, though still a little confusing. Here, I needed my passport and proof of vehicle ownership. The vehicle ownership document is just my registration document I received when I purchased the vehicle, so nothing special there.

No extra photocopies were required.

I did not need to present my driver’s license, despite having a valid one. Nor did I need to present any international driver’s license (thankfully, since there is no international driver’s license valid for South Africans to drive in Bolivia)

There was only one step I was unable to complete. It is required that a “Sivetur” form (or Formulario Sivetur) be completed. To find the form online, simply Goolge “Sivetur”. As of the time of writing, the link is:

The form requires you to specify details of your vehicle. Some of the values are just weird. For instance I needed to select a type of motorcycle and the options were things like “monkey bike”, “ninja”, and “chopper”, none of which applied to me. The idea is to select the closest match, despite your selection being possibly incorrect.

However, I was unable to complete the form because my license plate did not match the format used in Bolivia (which makes sense since my motorbike has a South African license plate).

This was not an issue. The friendly customs officer filled in the form for us, after Ana spoke to him and explained the situation. Having a fluent Spanish speaker with me made all the difference.

Crossing the Border

When we arrived, a guard immediately told us we will not be able to cross. Vehicles were not allowed to cross the border. This was disheartening, but we had come all this way so we parked and waited in the queue to see what would happen. The guard was wrong. We could cross. We did not need any special service, or permission, or anything of the sort. Yet more incorrect information.

We waited for less than 15 minutes before being processed. But there is little to no shade there. The processing is done out in the open, not inside a building. There are a few small trees, but not enough to offer protection from the sun.

The process was different from every other border crossing I had done (I’ve crossed from Uruguay to Argentina, to Brazil, to Paraguay, to Argentina, to Chile, and done that quite a few times now).

All documents for both Argentina and Bolivia were required immediately. You do not exit Argentina, then enter Bolivia. You provide two copies of EVERYTHING at once. Because we were not expecting this, we were slow to retrieve the mountain of paperwork that was suddenly required for two people. The border officer took us aside and collected the papers. We had no idea that copies of everything would be required here as well, but thankfully I had made three copies of everything so we didn’t run into problems.

To be clear, all documents for exiting Argentina and all documents for entering Bolivia were required by BOTH Argentina AND Bolivia, and all documents were collected up front.

I was literally kneeling on the floor finding the required paperwork while Ana acted as translator and kept the guard busy so he wouldn’t just leave us there because we were unprepared. Do yourself a favour and arrange all your documents neatly, then staple related documents together to avoid the same bad experience.

The documents will be collected and you will be left outside in the sun. Some time later, an officer from Bolivia will walk across to the Argentina side and collect the submitted paperwork before returning to the Bolivian side. This may be immediately, or in 10 minutes, or in 30 minutes, or an hour. You just need to wait. In the sun.

After what seemed like forever, but was closer to 3.5 hours from the start of the ordeal, our paperwork was successfully processed. We were given a form and instructed to rejoin the queue. A short wait later and we were processed again. There was some minor problem, but it was resolved within 20 minutes and we had successfully passed migrations on the Argentinian side only.

Because I was bringing a motorbike across, we needed to speak to Aduanas (customs). After a bit of back and forth (they did not want to release the bike from Argentina until we were certain the bike would be allowed into Bolivia, so we needed to check that first), we waited in line for the bike to be processed. The waiting and processing took a combined one hour, approximately. During this time, we were told we were lucky. Sometimes it takes 2-3 days to cross!

After passing through migrations for Argentina, and then Aduanas (customs) for both Argentina and Bolivia, we finally got to migrations for Bolivia. This process was pretty smooth. My passport was checked and I received an entry stamp.

I enquired and it turned out I could have gotten my visa there i.e. visa-on-arrival. But the embassy at Salta was unaware of this. So the 1.5 day delay was mostly just a waste of time.

After around 5 hours of processing at the border – by far my longest border crossing, we crossed into Villazon late enough in the day that it was unwise to make our planned trip to Tarija, 4 hours away. We found a hotel and spent the night.

The Joke

While approaching the Bolivian migrations office, we crossed a bridge and could see people illegally cross the border at their leisure, in full view of all the customs officers and border guards. Nobody cared. It really made me wonder if we’re not the idiots for following the rules.

And Some Days Just Suck …

I’d been in Bariloche, Argentina for 4 months. I really like that town. It’s not exactly quaint, but still small enough that I remember it as such. I went down there to wait for the borders to open so I could finally leave the country but Covid got worse and the frontiers remained shut to overland travel. Still, I took comfort in knowing I would get to spend my first snowy winter in a town I love.

But the snow was delayed this year. A bitter cold gripped the town and I felt the sort of cold South Africans are not built to handle. It got so I rarely left the house, going out mostly for food and an evening run. But the snow stayed away and my hopes of learning to ski and having my first ever snowball fight seemed dashed. Still, the winter promised to be long, and time was on my side.

Even better, the rate of vaccinating the public against Covid was increasing as well. Several countries even seemed to be allowing vaccinated tourists entry and rumour was Chile would be joining that list. Health, safety, and travel made for 3 excellent reasons to be vaccinated as soon as possible. The word on the grapevine is life might just be returning to normal around September, especially for the vaccinated. And I was, and am, very eager to continue my trip.

Except Bariloche made no provisions for vaccinating foreigners. I went to the clinic and in order to be guaranteed a vaccine, I needed to register. That could only be done in Buenos Aires. I could technically be vaccinated in Bariloche, but I would need to show up every day at closing time and if they had spare stock I would receive a jab. That wasn’t guaranteed though, meaning I needed to keep trying in the hopes of getting lucky.

So the plan was to head back to Buenos Aires. Accommodation was arranged and paid for. And the day before leaving it snowed. It properly snowed. The back yard was covered in white and enough landed that I even had a snowball fight. It felt bittersweet leaving the next day, especially since what I’d been waiting for since March finally arrived, but it was time to go.

The next day, Saturday, we (Ana and I) packed, said our goodbyes, jumped on the bike and left. Three metres later the rear tyre went flat. Not three kilometres. Not three hundred metres. Three metres. And surprisingly, it went completely flat quite suddenly. Thankfully there was a service station just one kilometre up the road but I soon realized the tyre didn’t just go flat, it came off the rim. And the snow from the previous day turned the not too gentle hill leading to service station into an ice rink.

Slowly, very very slowly, and very very carefully, I rode a sliding motorcycle up a slippery slope, on a very busy road, in the hopes of solving the tyre problem quickly since the trip to Neuquen promised to be very long. Ana was dropped off be the side of the road and she headed to a cafe for coffee.

I made it to the station. The rear wheel was not a pretty sight. I was surprised I made it to the service station at all! In near freezing temperatures, Ana and I removed the wheel, assessed the damage, managed to reinflate and refit it. We had the pleasure of sitting in muddy puddles through the entire experience. Still, a reinflated tyre was hope of finally leaving. I did a quick test ride but on returning, those dreaded water bubbles appeared on the side of the tyre, a clear indication the problem was not solved. I needed to get it assessed by a professional.

Time was short. I set the hard limit at 2pm. Anything later and we would need to find alternate accommodation in the city. Leaving at 2pm, even without stopping, meant we would arrive at our destination at least 2 hours after dark, and things got really cold after sunset. I rode to the other side of town to a gomeria – basically a car and/or bike workshop for common problems like tyre repair – and asked if they could help me urgently. The owner said sure, but he just needed to do something quickly. As I waited outside for him to finish up his minor task, a teenage boy opened a garage door. Lo and behold, the owner drove out, two kids jumped into the vehicle and he left. I sat there waiting, the seconds slowly ticking away, and the situation looking ever more dire.

My options were limited, so I waited. He returned around 20 minutes later. There was no point being angry. Too much had already gone wrong. He removed the wheel, inspected the tyre, and informed my the wheel, not the tyre, was defective. This was bad. Getting a new wheel in Bariloche may take a week or three. And oddly, the wheel seemed to be perfect. Even the mechanic couldn’t find any fault. Yet the little water bubbles were still there. He had an idea. He removed and refitted the tyre the wrong way and rechecked. Thankfully the bubbles were on the other side of the wheel! The wheel was fine, it was a defective tyre! It didn’t look defective at all, but he defect – whatever it was – caused the tyre bead to break off the rim resulting in spontaneous deflation. I had ridden for 700km on that tyre without problems. I may never have the problem again, or experience another blowout in the next 5 minutes. There was no way to tell. Still, a defective tyre was a much better problem to have than a defective wheel since tyres could be found relatively easily. Except it was Saturday, and after 1pm. All the stores were closed by now. I would need to get it fixed on Monday.

Our previous landlord didn’t have space, but thankfully knew of an apartment in town. So we headed off to the other side of town, pretty down in the dumps, wet, and frozen, and grudgingly ready to pay a small fortune for 3 nights accommodation in a town we very much wanted to leave at this point.

Argentina won Copa America that evening. After 28 years the cup was once again coming home and the country went crazy, with celebrations continuing well into the morning. It made our shitty situation feel a lot less shitty. I was thankful for that.

On Monday I replaced the tyre and early on Tuesday we said goodbye to Bariloche again. I was not prepared for the cold that followed. I wore 3 pairs of pants, 4 jackets, a beanie, extra thick winter socks and two pairs of gloves, but I still felt it. I have hand guards on the bike, but the wind still hit my fingertips and even with hand warmers, my fingers froze. Initially they were just cold, then very cold, then painfully cold, then so painful I could barely feel anything. The ride was through the mountains towards Neuquen. It was the most direct route, and we had to get through, so I pushed on. The pain eased off, and 2 hours later we exited the mountains, my fingers frozen, but with a warmer, sunnier ride ahead.

We stopped by the side of the road to take in the view. I marveled at how well my hands survived the cold when the pain hit. My fingers ached like they were being crushed. That’s when I realized how bad things were. I tried to heat my hands by placing them near the radiator and near the exhaust but it made little difference. A week later I hadn’t fully recovered feeling, and two weeks later the skin cracked and started peeling away. After a painful few days my fingers are finally back to normal.

The trip to Neuquen continued uneventfully until, with just 40km to go, we were stopped at a routine police checkpoint. It was one of those license and insurance scenarios. I produced the paperwork and to my horror, my insurance had expired. I hadn’t been on the road for so long that I completely forgot to check. No insurance meant the vehicle was not allowed on the road. We would need to leave it at the police checkpoint until the problem was resolved. This wouldn’t have been an issue earlier in the day, but it was after 6pm and the insurance office had closed. I contacted my broker who was able to convince a lady working at the insurance company to go back to work and renew my policy immediately. After a tense 90 minutes, the problem was resolved and we arrived in Neuquen in tact, though much later than expected.

Waiting at a police checkpoint for insurance problems to be resolved

Check-in was a breeze and we settled into our new apartment for the next few days. It was a nice spacious place, with a great Internet connection which was a welcome change after the last few months. Things were looking up, finally. After tyre blowouts, and unexpected expenses, and frozen fingers, and insurance problems, we could finally relax. I went to the kitchen for a snack later that evening and … roaches. Everywhere. They hung out in the bathroom too. Apparently the previous tenants were not too clean and left meat in the microwave that had gone moldy. As a bonus, the apartment hosts didn’t seem to be paying careful attention to the cleaning lady who wasn’t doing her job properly.

And that’s how the story ends. With roaches. One of the hosts showed up the next day and very apologetically set a variety of cockroach traps which made the situation much better, but the roaches were still there. It was just 4 nights so we didn’t move. The rest of the trip included an uneventful week in Santa Rosa, La Pampa and an overnight stay in Bragado. Ana and I are now back in Buenos Aires waiting to be called to receive our vaccines. Getting here was really no fun.

Like the title says, some days just suck.

Slow Days And Entertainment For Long Term Travelers

I am in Bariloche, Argentina, overall my favourite part of the country. There’s lots to love about this place – the beautiful lake, the surrounding mountains, the amazing views of snow coming in for the winter. Even the town is prettier than most.

Yet I’m sitting at home watching videos on my phone.

It seems like a waste, having traveled halfway around the world to do what I could have done back home. When I started traveling having slow days like this made me feel guilty, like I’m wasting a critical opportunity to go exploring, or sight seeing, or hiking, or whatever. But when you travel long term a mindset shift is needed. A shift that says this is life now, not just a 2 week vacation. That time is not horribly limited. That you can take it easy and relax. When you travel long term, every moment doesn’t count. You don’t need to stress out trying to cram maximum fun into your limited schedule because your schedule isn’t limited.

Which leads to the question of what do you do on those slow days? Of course what qualifies as good entertainment is subjective, but here’s a few things I’ve learned along the way.

Space Matters

I’m traveling by motorbike, and with a pillion. If you’re traveling light, space will always be limited, so choosing things to keep you entertained are equally space constrained. This leads me to the single best entertainment tip I have …

Get A Great Phone

Don’t settle for good if you can afford great. In addition to being a great travel tool in general, a good smartphone will easily provide the most entertainment in the smallest package.

Want to read a book? Check out Google Play Books, or the Amazon Kindle app, or load your own PDFs. Want to watch a movie? There’s Netflix, HBO Go, Amazon Prime Video, YouTube, and a ton more options. Want to play a game? Chat with friends? Listen to music? Keep up to date with social media? Check, check, check, and check.

You’re probably carrying a phone anyway; we all do these days. Which means the added entertainment benefits take up no additional space, nor do they add any additional weight. Many people say to live in the moment, don’t look at your phone, enjoy the experience. I agree, when you’re not having a slow day. When you want to kick back and waste some time, the best phone will offer the best way of doing it, which is why I don’t mind paying a little extra for a phone I really like.

Get A Chromecast

It’s a game changer in many ways. I mostly live in AirBNBs, and most have TVs. However the services offered vary greatly, from nothing, to a full entertainment package. A Chromecast or similar means video on a big screen. This is not guaranteed of course – it assumes the TV has HDMI support, but most do.

The device is tiny so carrying it shouldn’t be a problem. Overall, it’s just great to have.

Get A Nintendo Switch

This only applies if you enjoy games. I carry my switch around without the docking station. I bought a case that lets me carry a few games along with the console, and I added a pair of headphones as well. It’s great at airports, on planes, ferries, and perfect for slow days on the couch.

The entire package fits comfortably into my backpack and since it’s charged via USB-C, I just use my phone or laptop charger.

Running Shoes Are Awesome

I enjoy running. I have big feet. But I compromised on space and brought my running shoes with me. Many travelers have a more minimalist mindset and use one pair of shoes for everything. I disagree. Running is important to me, and I love my running shoes for the comfort and pain-free experience they afford me.

Of course your tastes may vary. Carry whatever additional gear you need, maybe for hiking, or climbing, or whatever you like. Personally, knowing I can go out for a run and enjoy it is a huge win!

What About Tablets, Laptops, Book Readers?

Technically you can carry whatever floats your boat. I work on the road and for that I have a laptop. I use it primarily for work. Technically I can use it to replace many of the entertainment tasks I perform with my phone, but it’s just not convenient. I hate lying in bed with a laptop on my chest.

I’m still pro-phone.

Ditto for tablets and book readers. Yes, a Kindle offers a better reading experience, but the kindle app works great and I generally don’t sit in bright sunlight reading books anyway. And a tablet is just a big phone. Unless you really need it, save the weight and space and leave the extras at home.

I think everyone enjoys sitting back, relaxing, and just taking it easy once in a while. But this poses unique challengers for travelers, especially long term travelers. Keep things simple, and small, and light. Get a great phone. It’s probably your single best travel investment.

How To Live On The Road Indefinitely

If you’re thinking about long term travel, especially by adventure motorbike, this post is for you

I left South Africa on 13 March 2019 and arrived in Uruguay a day later. Six weeks after that my motorbike arrived and I’ve been traveling through South America ever since. The plan was to just see Patagonia, but I discovered I loved traveling like this and thus far I’ve seen much more. What was meant to last a year is approaching 2.25 years, and while I may need to return home to get some paperwork done, I plan to return and continue for as long as possible.

I have things set up such that I can travel indefinitely. I don’t have a time frame.

If you would like to do the same, here’s what you need to know.

Money Is Important

If you plan on traveling long term, you need an income stream. For most people that means getting a job. Some people can live off investments. Others scrape by making and selling trinkets, or selling their travel pictures and stories.

Regardless, you need money. Money for food, accommodation, fuel, entertainment, clothing, and just general living.

Do not rely on your savings – unless you are really wealthy.

Savings are good, but they run out. If you rely on your savings only, the amount of time you spend on the road is directly proportional to the amount you have saved. Savings – again, unless you are very wealthy – will not sustain you.

I work as a programmer. I have fixed clients in South Africa who pay me every month. Rather than spend the money renting an apartment in Cape Town (which I did for almost 10 years), I now use that money to travel. My travel expenses are similar to my expenses back home. Some months are more expensive than others, and some are cheaper, but in general my expenses while traveling do not exceed my income. As a result, I can travel for as long as I want, provided my income stream is not affected.

The vast majority of people who travel like I do work in some digital field. Programming, digital marketing, writing, blogging, and making YouTube videos for a living, are all attractive options because in general all you need for work is an Internet connection.

I have also met people who make and sell art to support their travels. I have met people who make jewelry that they sell at the beach. What you do and how you do it doesn’t really matter. Just remember, money is important, and you need it coming in constantly!

The Things You Own …

“The things you own end up owning you.”

That’s a quote from the movie Fight Club. It may sound cliched, but it’s also true.

Back in South Africa I rented an apartment, I had a bakkie (called a truck in the US, or a ute in Australia), and 2 dirt bikes. I had 2 closets full of clothing I didn’t wear much, and another closet full of gadgets. I also had DVDs, a large TV, Playstation, and a bunch of other things I rarely used.

When I decided to do this trip I sold almost everything. I compressed my South African life into 2 medium sized suit cases that are stored at a friend’s house. The rest was sold, thrown away, or donated. I do not miss it one bit.

You probably only need a tiny fraction of the things you own. The rest are holding you back. People never leave on their road trips because they have too much stuff. An apartment or house to pay off (have you considered renting out?). Furniture, dishes, clothing, vehicles. They aren’t important. Families are a complex beast. I don’t have one of my own so I won’t comment. But most material possessions are dead weight. You only realise how little value they add to your life when you no longer have them.

My possessions are now my bike and whatever I can fit into 1 pannier and half a large duffel bag. I have a full time pillion now so the other pannier and half duffel bag are hers.

If you want to leave, get rid of what you don’t need. And you need very very little.

You Probably Want Less Adventure Than You Think …

Camping is paying a fortune to live like a homeless person. I have camped. I enjoy it because it’s a change from the norm. But on most days I want a bed. I want an air conditioner in summer and a heater in winter. I want decent food, whether that’s eating out or cooking for myself. I want a comfortable chair and table and great WiFi so I can work without problems, and stream TV shows on Netflix.

Full time adventure is great in theory, but since travel is my life, not my holiday, I need to fulfill my life responsibilities. And I don’t want to do that from a tent. Being adventurous 24-7 just isn’t fun (at least not for me). When life is an adventure all the time, it’s not an adventure anymore. It’s just your new normal.

On a weekend trip at home, go all out and be as adventurous as you like. When you travel as a regular part of life, things are different.

I started out with a tent, sleeping bag, camping chair, stove, camping pot, tons of recovery equipment, and extra clothing.

After 5 months of the extreme cold and not wanting to sleep outside at all, I ditched the tent. The rest of the camping equipment followed soon after. Along the way the extra clothing was either thrown away or donated. And I got rid of some of the recovery equipment I didn’t see myself using.

I mostly live in AirBNBs. I look for good WiFi and I generally favour more spacious places. I want most days to be normal. I get up, work, run, explore the area by bike or on foot or even take public transport. And when I’m ready to move on I have another road trip with great sights and twisty roads. Pre-Corona, I moved around twice a week. Do that for a year and you appreciate the importance of stability.

I also travel at the speed limit now. South America is a slow continent and I just got used to it. Why burn up tons of expensive fuel to save 20 minutes on my trip? Does it really matter? In South Africa I rode much faster. 20km/h above the speed limit was pretty usual but back then, I traveled on weekends and holidays only, and usually to familiar spots. Now, every few days offers a new experience through landscapes and roads I’ve never seen or ridden before. Sure I want to enjoy the road when it gets twisty, but I also want to enjoy the sights, take it easy, live in the moment.

Talk Is Cheap

I know many people who talk about all the amazing trips they will do one day. About how they will live like real men. Pluck cups of coffee right off the tree like nature intended. And then they go back to their regular routines.

A few years ago I met a man who spoke about a trip he was planning. His ambitions were greater than most. He wanted to ride around the world! But he was naturally conservative, and very measured in his approach to “adventure”, planning every detail meticulously. He seemed like the least likely adventurer in the world. He didn’t brag about the skills he didn’t have. He didn’t talk about all the amazing routes and tough roads he was going to ride. He just didn’t seem too adventurous.

Two years later he’d been through Africa, some of the US, and he’d ridden through the Himalayas and parts of Europe. He didn’t talk about his plans, then go back to a regular life. Instead, he had a dream and followed it.

Before leaving on my trip I asked him for advice. He was the only person I could ask; nobody else had accomplished nearly as much. He knew, and had experienced, far more than me. I was a talker, he was a doer. I talked about doing great things. He quietly did great things.

Be a doer, not a talker.

This Isn’t A Life For Everyone

I’m a loner. I don’t mix well with people. I don’t usually miss home, or miss family. And I don’t understand why others do. I was made for this temporary life of travel.

Not everyone is the same. I wasn’t sure if I was ready for this life either not too long ago. Back in 2018 I traveled to Asia for 4 months, alone, to see if I could handle such a drastic lifestyle change and I discovered I loved it. I committed to my current South America trip soon after.

You may not be the same. That’s OK. And if you’re not, following the advice here will bring you nothing but misery.

Wrapping up, you need money; don’t believe people who tell you otherwise. You need the courage to leave an old life behind, and also the courage to start something new. But remember, just because people speak highly of travel doesn’t mean it’s for everyone.

Good Luck!

A Back Roads Trip Across South Africa

A little before Christmas 2017 I spontaneously decided to do a road trip from Cape Town where I lived, to visit my parents in Pietermaritzburg about 1600km away. I normally fly up but being the holidays and eager to get out for a long trip, I thought it may be a good idea.

The plan was to avoid freeways as much as possible and stick to the gravel farm roads, of which there are many. To make things more interesting I also decided not to book accommodation in advance. I would drive as much as I wanted, then look out for a place to stay. South Africa is not a safe country, but I figured I would be far enough away from major towns that safety hopefully wouldn’t be a problem.

I aimed to cover the distance over 4 days. On the first, after a peaceful ride through the farmlands, I found a camp site offering decent facilities around sunset. I was allocated a spot in the shade and pitched a tent for the night. It was a decent start to the trip and while nothing spectacular, I thoroughly enjoyed being on the road, alone, and for the most part in the middle of nowhere.

Without realizing it at the time, I was learning to enjoy solo travel. And this, along with a few experiences after and a few before, prepared me for my current two-years-and-counting South America trip.

Day 2 started much like the first. I was quietly riding through some back roads, again without another person in sight, when I spotted an adult kudu – a type of antelope found locally – eating by the side of the road. Not wanting a problem, I slowed down and kept driving while giving the animal a wide berth. All seemed well though. I hadn’t scared it. Those little precautions help keep travelers much safer.

Then, as I got dangerously close, the animal darted across the road in front of me. I slammed on the brakes with enough room to spare. But just as relief set in, a baby kudu I hadn’t noticed at all blindly ran after its mother and slammed into the passenger side of my vehicle with enough force that I almost lost control.

I stopped perhaps 50 metres away and inspected the damage. There was a huge dent on the door and some blood stains. I walked back to the site of the accident and saw the baby lying by the side of the road, still alive, and trying to crawl under a barbed wire fence with a broken leg. Kudus normally hop those fences with ease.

Kudus, even baby kudus, are huge. Even if I miraculously was able to lift it and take it to the next town, it wouldn’t let me. It was a wild animal. I got some water and tried to feed it but it refused to drink. I jumped back into my vehicle and thought I would seek assistance at the nearest farmhouse. Before arriving though, I came across a farmer and explained the situation. He drove back to the scene of the accident with me but after inspecting the damage he said there was nothing we could do. Apparently wild kudus run across roads and into vehicles pretty frequently in those parts. No matter how high the fence, they always manage to get through. While it was a new experience for me, the farmer had apparently been through this many times before. He said to keep going and that he would fetch his gun after running some errands, then put the baby out of its misery. I noticed the mother watching us from a field next to the road. But I took the farmer’s advice and left.

That evening I found accommodation at a little one-horse town in the middle of nowhere. I paid the proprietor, Mike, and offloaded, then went back to reassess the damage to my car door. Mike sidled up to me and in the tone of voice not far removed from a drug dealer asking if I was interested in his product he asked: “You a Muslim?”

I am. And Mike, a big, plump, Caucasian who shared more than a passing resemblance to a boer (farmer) but with blue shorts – farmers in South Africa favour khaki – was a Muslim too. He looked nothing at all like I would have expected. Shame on me for presuming I guess. He took me to his living room where a huge crucifix and a picture of the Virgin Mary adorned the far wall and for a moment I wondered if he had his religions mixed up. Shame on me twice.

Mike told me about accepting Islam pretty late in life. The rest of his family were Christian, but they all got along well enough by following a policy of agreeing to disagree. He also told me about his favourite past time of annoying the other religious folk in town who were not thrilled that a good church going man in his sixties turned to the dark side.

The following morning, Mike appeared as I was packing to leave and said he wanted to show me something. He runs a little motorcycle museum specializing in old Hondas. He is also a Freemason, and devoted a section of the museum to his collection to prove it. Finding an interesting, rebellious, White, Muslim-Freemason-Biker-Curator in the middle of farmland and Bible country was, without a doubt, a highlight.

What I thought would be a short visit ended up lasting almost three hours, and I was given a personal tour of everything. I was meant to be on the road by 10am. I left closer to 1pm with around 6 hours of light remaining. Still, it was a good delay.

The eastern half of the Eastern Cape, where it meets Kwazulu Natal, offers some of the most breathtaking scenery in the country. In my effort to avoid freeways I chose to head through the mountains and find accommodation before nightfall. The mountain scenery did not disappoint even though earlier rain had turned the roads muddy and progress was slower than expected. At sunset I found myself at Naude’s Nek, one of the highest mountain passes in the country. Several years earlier my friends and I camped here unexpectedly on a motorcycle adventure ride gone wrong. And once again I spent the night at Naude’s Nek though, unlike the motorcycle adventure, I was well prepared this time.

The night was terribly windy. The temperature dropped to almost freezing. But it was just me, in the middle of nowhere, with not another soul in sight. I loved it. The view in the morning was one to die for. Rolling green hills as far as the eye could see, with mountains at my back. Spectacular does not do it justice.

I drove down, enjoying the view and the road thoroughly. Perhaps my only regret, and one I shared on a similar trip to Chile earlier in the year, was that I did not do it by motorbike.

After around 90 minutes of stunning mountain scenery I joined the main road. I had less than 150km to my destination. It had been an incredible 3 days thus far. I used the freeway for the remainder of the trip.

Ciudad Del Este, Paraguay

I knew nothing about Paraguay aside from its location before arriving in South America. Asking around in Uruguay and Argentina, the locals shared a common theme when speaking about Paraguay: “There be dragons!!!”. Not a single person recommended I visit the country. Honestly, the best anyone had to say was “you won’t miss anything”.

My plan was always to head south after arriving in South America but the cold forced me north at least until Spring, so I found myself at Tres Fronteras where 2 rivers intersect and form the borders of Argentina, Brazil, and Paraguay. The plan was to cross Paraguay, re-enter Argentina, then head south. Since there is no direct land crossing between Argentina and Paraguay there, I first traveled to Foz de Iguacu in Brazil, then on to Ciudad Del Este, Paraguay. The total travel distance between these three countries is probably less than 10km.

The border crossing was something to remember. There were several very long queues to enter the country by car or bike, and the pedestrian bridge separating Brazil and Paraguay was overcrowded with people also trying to enter. But oddly, there seemed to be motorcycle riders all wearing yellow helmets, and usually carrying passengers, who entered and left with ease. Those bikers carry passengers between Brazil and Paraguay for day shopping. The agreement is they enter with minimal fuss, the passengers shop for the day, then return home to their own country. What surprised me most is almost no checks were performed on these passengers. Yellow helmet bikers and their passengers were just waved in; not even passports were checked in most – almost all – cases. If I wanted, I could have arrived in the country illegally by yellow-jacket bike and disappeared into the crowd like Hannibal Lector to start a new life as a face eater or florist or whatever.

When I finally arrived at passport control I was taken aside. Apparently not many “foreign” tourists cross those borders by motorbike. “Foreign” is an interesting concept in South America. Much like the EU each country is different, but agreements exist to allow for easy travel between certain countries. So a Brazilian entering Paraguay or an Argentinian entering Chile has few problems. But a South African entering Paraguay by motorbike from Brazil is far less common.

After waiting a short while, I was taken to a tiny office in the middle of traffic. There was a desk and some notebooks but no computers. I waited alone until a police officer fetched a second officer with a laptop to process my visa. After regular document processing, I was handed a hand-written slip of green paper that confirmed everything was OK. I honestly do not recall ever being handed a hand written form at a border crossing before or since.

Now, the South American countries I visited all have the certain similar problems. One of the bigger issues I knew nothing about before arriving is the high price of foreign products. Uruguay places a 70% tax on all incoming items. In Argentina many popular products sell for 2 to 3 times the price as other countries. iPhones, laptops, motorcycle parts (depending on the motorcycle) can all be found, just at ridiculous prices. Of course the bonus is food, accommodation, and local products in general (either Argentinian or one of the trade partner countries, typically in the Mercosur region) are cheap, and it’s not like I buy laptops every other week so the pros outweigh the cons for a traveler.

And this is why Ciudad Del Este is so popular. Centro (Downtown), is a massive duty-free shopping mall. I don’t just mean there is a shopping mall downtown even though that exists too, I mean almost all of downtown is filled with a variety of shops offering duty free shopping for travelers.

Centro is not much to look at. It is mostly dirty with shopping opportunities everywhere, on every pavement and in every alley. Tiny make-shift stalls stand alongside huge department stores, but they all share the same dirty roads. And much like a busy shopping mall, you will often find yourself rubbing shoulders with strangers. Trading hours are always hectic.

The range of shopping experience is huge. In one minute you can go from small-time store selling knock-off watches to a proper first world shopping mall experience with climate control and the best of everything, then back to small-time store as soon as you take a step out the door. Depending on where you go, many first world items are available for sale at familiar, non-South-American prices. This more than anything is the big selling point of the city. Travelers from surrounding countries visit Ciudad Del Este to shop, nothing more.

The Goldfox 6. Like that other gold camera, but not quite as pro

Changing money is equally interesting. Sure you can go to an official exchange, or do what I do an withdraw cash from an ATM. But the more popular approach is to find a seller on the street – basically a person carrying tons of cash in various currencies – and negotiate a rate with them. I got a better deal than the ATM.

The rest of the city is … I want to say under developed but that would be doing the city an injustice. Poorly developed may be more accurate. The best of the best you could expect in a city is interspersed with areas best described as dodgy. I was warned not to be out alone at night. I was warned by the host of the AirBnB I lived in that should I have any problems with the police to have them contact him because he can deal with it. Non Paraguayans warned me I may need to pay bribes if stopped by the law, and that the country is extremely corrupt and dangerous so to be on my guard.

Thankfully I had no bad experiences whatsoever. South Africans are generally familiar with dangerous cities so perhaps that’s the reason I adapted well. But Ciudad Del Este was the only city that, in many ways, felt too familiar for my liking. Argentinians and Chileans complain about their dangerous cities, but what they consider to be dangerous I always felt to be safe. Not in every circumstance of course, but as a general rule. Ciudad Del Este felt a little too much like home. I felt safe in the crowd, but I also tended to look over my shoulder and avoided more isolated areas not because there was any obvious danger, but because as a South African I knew that’s where trouble would be.

I spent a few days in the city and bought a shiny new Garmin watch at a reasonable price to track my jogging. My next destination was Asuncion and once again, I had no problems. When leaving the country I handed in the handwritten green slip of paper I received on entering. The guard glanced at it for maybe two seconds and let me through without even punching any data into the computer. I double checked if everything was OK but he seemed annoyed and just waved me on to Argentina.

Falling In Mud

Some days just suck. There’s no bright side. There’s no lessons learned. There’s no looking back years later and laughing, thinking it wasn’t so bad. The day sucked then, it sucks now, and it will suck forever more. That’s the summary of my ride from Gualeguaychu, to Buenos Aires.

I entered Argentina from Uruguay 3 days earlier via the Fray Bentos border, traveling from Mercedes, Uruguay to Gualeguaychu, Argentina. Gualeguaychu is a small but typical border town. This was my first experience of Argentina. The next stop was Buenos Aires but rather than follow the main freeway I found a few farm roads leaving town and connecting to the main road. It would not extend my trip by much (maybe 6km) but turn a boring city-to-city all-tar ride into something a little more interesting.

There was a light rain the night before I left and the morning of my departure promised more that afternoon, but the roads were fine. Turning off the tar, the road was light gravel with just one minor deep sand patch for around 100 metres. After perhaps 10km there were hints of mud and the road getting a little tougher, but not enough to be a deterrent. Things went south fast though, and only a few kilometres later, well … the pictures tell the story.

The bike was down but I’ve fallen many, many, many times before and I knew how to recover. What I wasn’t expecting was the slipperiness of the mud. My feet couldn’t get sufficient traction to lift the bike at all. Thankfully two men in a 4×4 showed up soon after and helped. Realizing the foolishness of continuing with the road only getting worse, I turned back, thankful for help arriving so soon.

Then the rain started and made the return path increasingly dangerous. So when I found a shorter road to the freeway, despite me not knowing what to expect, I thought why not? Instead of traveling another 16km, the shortcut promised to get me out in just 3km. Sure it may be a little slippery, but 3km! I was tired, and sore, and at that point I just wanted it to end. It was a seriously stupid decision.

500 metres later I encountered a horrible mud patch. The bigger problem was I couldn’t turn around without risking a fall and with no help in sight so I went forward, barely keeping the bike upright. I made it. Only 2.5km to go. There was a small hill coming up, tiny really. I had to make it up. The road was so slippery that if I stopped I wouldn’t be able to get going again. And since turning around was out of the question, at least without serious risk of falling and not being able to get up, I had to make it up. I opened the throttle and hit the base of the hill as fast as I dared. Halfway up the bike started sliding around dangerously, turning almost completely sideways at one point. I held on and against all my instincts I didn’t hit the brakes, I didn’t go faster, I just stayed in control. I did it. I made it up the hill. It was one of those glorious moments where I knew I’d achieved something far beyond my skill level. I was beyond happy – just elated. And 2 seconds later I fell.

I was 1km from the freeway. It was just around the corner. But the mud was so slippery I could barely stand. The tyres were caked in mud. I had TKC80 knobby tyres but I may as well have been riding on slicks.

I offloaded the luggage from the bike, sometimes crawling in the mud to do so, but it made no difference. I couldn’t lift the bike at all. I couldn’t even drag it to the edge of the road. I was out of energy. Just completely exhausted. And the mud made it almost impossible for one person. I sat and waited. I didn’t have the strength for much else.

Some time later a group of farm workers were passing and stopped to help. We easily lifted the bike; 4 pairs of hands made quick work of the task. I loaded my luggage onto the back of their 4×4 and they escorted me to the freeway. That last 1km was easy riding, as it turned out I fell at the very last obstacle, which was the worst of the road. I packed my bike, hit the freeway, and rode to Buenos Aires without further problems.

That day sucked.

Using State Machines For Simplified Message Processing

A problem developers face is extracting messages from a byte stream. This post covers a strategy for accomplishing that task.

This is not a problem typically found in higher level coding spaces. Much of modern development has been relegated to the realm of HTTP and web servers, or other middleware such as message queuing systems that abstract away the problem behind some library.

Lower level developers face this problem, often when working with embedded systems and interfacing with devices on memory constrained systems. More generally, this is a problem faced by all developers working with protocol implementations.

The Problem

Data bytes are streamed to an application from some source. This may be a file on disk, a network socket, hardware such as a serial port, I2C bus, SPI bus, or similar. An application reading these bytes needs to decode useful data from the stream, ignore noise, and recover from errors.

Consider a simple message having the following structure:



<header> will always be the byte value (0x55)

<footer> will always be the byte value (0xAA)

<data> is alpha numeric data i.e. a-z, A-Z, and 0-9 only.

The message is byte oriented; Unicode characters are not covered for simplicity in this case. A simple message may look like so (values in parentheses are single hex bytes):


And two consecutive messages may look something like this:


In both cases processing could be accomplished as follows:

  1. Allocate a 5 byte buffer
  2. Read 5 bytes (from disk, some bus, a network socket, etc)
  3. Ignore the first and last byte and you have 3 valid data bytes

This solution appears fine, but contains numerous problems including:

  1. The previous example was intentionally selected so both messages were the same size. The message specification places no limit on message size, nor does it specify that each message must be the same size
  2. Both messages above were examples of clean data – every read is assumed to return a valid message byte. The data stream is free of noise/garbage
  3. A buffer containing 5 bytes of clean data guarantees a full message will fit completely into a single buffer. There is no chance of the buffer containing a partial message. In reality partial message data is commonplace and a full message often needs to be constructed from repeated partial data reads
  4. Despite needing 3 bytes of data, provision has been made in the buffer for the header and footer framing bytes. Admittedly there are only 2 bytes so the overhead is not huge, but this is often unnecessary overhead resulting in higher than required RAM usage. For a server with 32GB of RAM this is not usually an issue. For a microcontroller with 512 bytes of RAM, this may be a problem.

To illustrate the problems above, consider the same 2 messages, but in a dirtier data stream.


The byte stream above contains 2 valid messages, highlighted below:


Now apply the previous solution:

  1. Allocate a 5 byte buffer (no problem here)
  2. Read 5 bytes. The problem starts here. Rather than read a full message we will instead have: (0x55)(0x55)ABC
  3. Discard the first and last byte. This leaves us with: (0x55)AB This is not a valid message

Repeat the process:

  1. Allocate a 5 byte buffer
  2. Read 5 bytes. This reads the following: (0xAA)(0x00)(0x00)(0x55)1
  3. Discard the first and last bytes and the message is: (0x00)(0x00)(0x55) This is not a valid message.

Repeating the process a third time gives the message data:


This is not a valid message

Repeating again produces the data:


This is a valid message!

Finally, we have one stray byte in the data stream

Therefore the dirty data stream resulted in missing one message completely. We successfully read the second message but that was coincidence. Had there been one more or one less stray byte in the stream between valid messages, both valid messages would go missing.

The Solution – State Machines

Modern reactive programming frowns on old fashioned ideas like state machines. They’re monolithic and don’t easily conform to the best practices recommended by testing frameworks. But not all old ideas are bad and state machines, while old fashioned, are both simple and powerful.

The state machine pictured below solves the problem. Before discussing how to construct the state machine, let’s apply it to the dirty data stream and see what happens. The data is also shown again below:


  1. We always start at the state marked “start”
  2. The first byte read is (0x55). We follow the arrow (known as an edge) to the collect state. We don’t need to collect this byte – we’re interested in the data only, not the “packaging” around the data.
  3. We read next second byte, also (0x55). Since we’re in the collect state, we follow the “Read 0x55 and restart collection” edge. This means discard any data we have collected (we haven’t collected anything yet), and remain in the collect state. So we’re ready to collect data again.
  4. Next we read ‘A’. This is a valid data byte, so we save it.
  5. The next 2 reads are for B and C, both data bytes, so we save them too.
  6. We read (0xAA). Following the appropriate edge, we transition to the “stop” state. We have a full message of data bytes only. In our naive solution we completely missed this message! The process then starts over by returning to the “start state”

Already we’re looking great. The first iteration of the state machine captured one message that would otherwise have been lost. Let’s continue processing the byte stream.

  1. We resume and the next byte read is (0x00). The start state only transitions to the collect state when (0x55) is read. Since we’ve read (0x00), we follow the “Not 0x55” edge and remain in the start state. The following byte is also (0x00), so once again we remain in the start state.
  2. We read (0x55) and transition to the “Collect” state
  3. Then we read the byte values “1” and “2” respectively. Both these bytes are saved. It looks like we have another message.
  4. But no! The next byte is (0x55). Since we’re in the collect state we follow the “Read 0x55 and restart collection” edge. All collected data is discarded. We don’t have a message after all, just a partial message. For our use case, that qualifies as garbage.
  5. The next three bytes are 1,2,3 which we collect since we’re in the “Collect” state
  6. But as luck would have it we then read a (0x55), So we discard all the collected data and restart data collection in the “Collect” state; we had another partial message.
  7. The next three bytes are 1,2,3 which we collect
  8. Then we read (0xAA) and follow the edge to the “stop” state. We have another message!!!
  9. We transition back to the start state and read 0x00. We can’t do anything with this, so we remain in the start state. This is the end of the stream

A second message was captured successfully. The thing is, it doesn’t matter how much noise is added to the system. The state machine is designed to look for what we’re interested in and discard the rest.

Try increasing, decreasing, or changing the noise between, before, or after the two messages in the data stream. Both messages will still be read successfully.

How To Build A State Machine

A state machine consists of, well, states. A state is like a snapshot in time of your processing logic. The state itself doesn’t do anything, but when something happens (eg. a new byte is read) the code either stays in the current state or follows an edge (i.e. the arrows) and transitions to another state.

The logic for each state should be simple. Similarly, the data fed into the state machine should be simple. Even if you read multiple bytes of data from the stream at once, always feed the data into the state machine one unit at a time. I say “unit” because in these examples 1 unit is one byte. In your state machine, one unit may be one UTF-8 character, which may be up to 4 bytes. That’s OK. Just ensure you work with the smallest unit of data that’s reasonable for your problem.

Let’s break down our message structure. It was described above like so:


The message is easily split into 3 parts:

  1. <header>
  2. <data>
  3. <footer>

That seems obvious, but that’s exactly the point. A state machine helps you do exactly what you want, simply. So we need to read the header, and then collect some data, then read a footer.

At a minimum we need 3 states, one to read the header, one to collect data, one for the footer. Now traditionally, state machines always have start and stop states. In the state machine diagram above, the header was read in the start state and the footer in the stop state. The collect state was for data collection. Other state machines don’t have the start and stop states actually do anything, they’re just there to indicate where processing should start and end. I’m trying to be a little more practical and using all states.

When building a state machine, start with the simplest case. Pretend everything is perfect and you have no errors in your system. Then draw the transitions that lead to success. It may look like this:

Basic state machine with no fault tolerance

This state machine so far is not fault tolerate at all but apply it to a clean data stream such as:


and you will get two valid messages. In fact, you can even change the message sizes and the state machine will still work perfectly. But only on condition the data is clean.

Now that you have a basic solution, the idea is to consider problems. But when doing this, treat every state individually!!! For instance when you’re in the “Start” state, you are only interested in what happens to the “start” state. Do not worry about what will happen at other states. You focus on one state only. At no point should something occurring in one state affect another state!! This is the beauty of state machines. Keep your thinking small and simple. There are no complex dependencies anywhere!

So, let’s consider the start state. We know we want to start the process by reading (0x55). We’ve already added that to our machine. But what if something goes wrong and we don’t get (0x55)? Well, it’s not what we want, so there’s no place for us to go. In other words, we should stay where we are. We dealt with this condition by drawing a transition for “Not 0x55” in the original state machine. That keeps us where we are, in the “start” state. Since we’ve catered for (0x55) and “Not 0x55”. That’s literally everything. We’re done here, let’s move on.

Again, don’t overthink things. Don’t create complex dependencies. Think about the state you’re dealing with only and nothing else. The most complex part of this process is realizing how easy it is!

The full state machine is shown again below for reference.

Next, let’s look at the “Collect” state. When looking at this we don’t care about any other states..

What do we need to do in the collect state? Well, we need to collect alpha numeric values. So if we we read() a byte in the range A-Z,a-z,0-9, we save it. But what about everthing else? Well, if we get anything else it means we shouldn’t be collecting data. So let’s look at what may happen:

  1. We get (0xAA). If we get that, we have a full message so transition to the end state
  2. What if we read (0x55) again? We could go back to the start state, but (0x55) means we need to start collecting data. If we returned to the start state, the next byte we read will be the second byte of the message which we should be collecting. Since we’re already in the collect state, that means we should just remain here i.e. that’s the reason the state loops back to itself. The fact that we got (0x55) instead of an end of message (0xAA) means we don’t have a complete message. That’s why we discard the bytes we already collected – we want to start over from scratch.
  3. Lastly, if we read any other byte we literally have nothing we can do with it in our message specification. If we read it something has gone wrong with processing. There’s no point in going to the end state since that’s where we go if we have a full message. What we want to do is start over. So just go back to the start

Like before, we’re simply looking at what do we want, and what don’t we want for this state only.

Lastly we look at the stop state. When we get here we have a full message. So process the message as required by your application. There’s nothing special that we need to do here. We’ve completed processing. Just start over.

And we’re done.

How to implement this?

The easiest way is a switch() statement. This works in languages like Java and C. Rust’s version of the switch() statement is “match”. For languages like Python, a simple if-else statement works perfectly.

I have a full rust message decoder on github for a more complex sample message. You can clone the repository at

Here’s some pseudo C code to illustrate processing:

typedef enum {
} states;
static states state = GET_HEADER;
void main() {
	sock = open_socket();
	while (1) {
		size = read(sock, buffer, 16);
		for (int j = 0; j < size; j++) {
			b = buffer[j];
			switch (state) {
				case GET_HEADER: {
					if (b == 0x55) {
						state = GET_DATA;
					} //else stay here. There’s nothing more to do!
				case GET_DATA: {
					if (b == 0x55) {
						/* looks like we have a partial message */
					} else if (b == 0xAA) {
						 * we have a full message. Start over. Don’t waste time
						 * going to a footer state that does nothing. Just start over		
						state = GET_DATA;
					} else {
						/* save the data byte somewhere */

And that’s it, a fully fault tolerant message processor that will filter out noise, discard partial messages, ignore overhead and allow for saving only data bytes.

From our state machine diagram, the STOP state didn’t do much, so rather than waste a loop iteration (and read() call), the GET_DATA state looks to see if we have a full message and if we do, it just starts over.

State machines are brilliant for message processing, but additionally for simplifying almost any complex problem. It surprises me that they aren’t used more often. I frequently see massively overengineered code made reactive with multiple layers of complexity to address problems that could be solved simply with an old fashioned state machine.

That’s all folks!

The Most Beautiful Road In The World

The Carratera Austral in Chile (Ruta 7) has a reputation as one of the most stunning roads in the world. Having ridden most of it, I confirm this reputation is well deserved.

My ride through Ruta 7 was split into pieces, having traveled from Puerto Montt to Chaiten some months earlier, looping back to Argentina via Gran Chiloe, then re-entering Chile via the Esquel-Futaleufu border. After a short stop at La Junta I ended up in Coyaique. The La Junta to Coyaique route was spectacular in itself, but that’s a story for another day.

The Coyaique to Los Antiguos trip was going to be long. The total distance was around 400km, but Google and Garmin both listed the travel time at around 10 hours. The route was almost entirely relatively easy gravel. The biggest problems tended to be dust, slow moving cars, and narrow roads.

But the relatively small problems were completely dwarfed by the amazing, stunning, just WOW scenery that filled the entire ride. The mountains, lakes, roads, snow – just everything – made what could have been a long and boring ride an absolute pleasure.

The tar road from Coyaique wound through snowy mountains to a peak overlooking a valley split by s-bends.

The gravel started shortly after with wilderness all around. For the next 160km I was surrounded by an ever changing mix of mountains, snow, forests and lakes as the narrow road snaked though hills and valleys. There were few wide open spaces but even then, snow capped mountains were either visible, or just around the corner.

After an exhausting few hours a familiar, but distinct change in scenery occurred. The space between mountains widened. They were separated by the bluest blue lake I have ever seen. Puerto Tranquilo was close by, and had I known in advance to expect such a spectacular sight, I would have stayed here instead of booking accommodation at Los Antiguos.

I stopped to refuel and grab a snack by the water, but the day was long and I still had several hours of riding ahead of me. Not wanting to be on these roads in the dark, I didn’t stay too long.

I branched off Ruta 7 and headed towards the border at Chile Chico via Ruta 265. The road bordered an unnaturally blue lake, backed by mountains with their tops covered in snow. I was exhausted, both physically and mentally. Sunset was fast approaching and I wasn’t sure if I would make it to the border on time so speed was essential. I passed several slower vehicles and ignoring the literal pain in my butt from sitting for so long, I kept going.

The road gradually climbed, then turned sharply right. And quite unexpectedly mine was the only vehicle in sight. I was riding down the side of a mountain with a perfect view of the most beautiful lake and snowy mountains I had ever seen. It was as if I was the only person in the world. I stood up and enjoyed my ride on the most beautiful road in the world.

I didn’t stop for pictures. My GoPro had long since died. Stopping would have given the slower vehicles an opportunity to ruin the experience. The only evidence I have of that view, at that point in time, lives in my memory. I marked the point on Google maps later that day. I was on Ruta 265, diagonally across from Puerto Cristal at approximately 46°36’15.5″S 72°20’09.2″W, a little before the switchbacks up the mountain.

I arrived at the border on time. That was my most beautiful ride ever.

There are 2 GPX files that make up this route. Here’s part 1, and part 2.

That Day In The Snow

I love snow … in theory. Which is to say I come from a country where it almost never snows and my very limited snow experiences have been great. The rest of my knowledge comes from TV shows.

Villa Pehuenia is a beautiful town at the edge of Patagonia in Argentina, and close to the Chilean border. I went there for the view, but also because there was the promise of a spattering of snowfall. Given that I had no experience whatsoever riding in snow, I was not willing to risk anything too hectic, at least not yet.

The plan was to arrive on Saturday and leave on Tuesday, with three days and nights to explore the town. Describing it as beautiful is an understatement. Villa Pehuenia, at least in the Spring, is the first town I have described as picturesque.

Leaving on Tuesday was intentional. I learned a long time ago to check the weather reports when on a trip, especially when planning to visit a snowy mountain town. Light snow was expected on Monday and Tuesday, with a full blown snow storm arriving on Wednesday. By my estimation, leaving on Tuesday would allow me to enjoy more snow than I ever had previously, while avoiding the dangers of riding through a storm but still getting some desperately needed snow riding experience. Snow and big motorbikes generally don’t mix well.

The light dusting of snow started a little before midnight on Sunday. It was everything I hoped for. But on Monday there was snow everywhere! Not a dusting, around a foot deep and definitely more than I bargained for. And the snow wasn’t stopping.

It snowed all day Monday and by the evening I was dangerously close to not being able to ride at all, which was problematic since my checkout was the following morning. I went to bed praying for the snow to stop.

On Tuesday morning, a full day early, the snow storm hit. There was heavy snowfall and the pattern was unlikely to change for the remainder of the week. I had accommodation booked in another town, and I didn’t know if I could even stay in my current accommodation. Moreover I was a little tired of the small town and I really wanted to leave.

So I packed up my bike and for the first time ever I planned to ride to the next town around 60km away, in the middle of a snow storm.

I rode slowly. My biggest concern was the next forty or so kilometres of mostly nothingness, with few houses, few cars, and no easily accessible help. I wore three layers of pants and jackets, two pairs of gloves, and a beanie under my helmet. Less than twenty kilometers later I was frozen stiff, my fingers barely able to move even with my heated handlebar grips set to maximum. I tried fixing that problem by keeping my hands close to the bike radiator whenever possible, but it didn’t help much.

Visibility was terrible, and there were times when I could see no more than a few car lengths ahead of me. I was the only vehicle on the road for the most part; I think only one passed me while riding through that small stretch of no-man’s-land, and the lack of visiblity meant I wasn’t able to even see the few houses along the route. Thankfully however, the road was not slippery in the slightest! One of my major concerns was the dirt road turning to mud, which would make the trip nearly impossible. But I quickly learned that while the road looked muddy, the gravel turned to a thick, grippy sludge instead of slippery mud.

The experience was nerve wracking. After 20km I was frozen, but I was also halfway out of the worst of it. Turning back didn’t seem smart. But what if the remainder of my trip got a lot more difficult? Wouldn’t it be smarter to turn back now when I at least knew what to expect? What if I fell and couldn’t get up? Would I freeze to death? It’s not like help was plentiful. Why were other cars not on the road? Were other people smart enough to know to stay indoors in weather like this, or was this just a coincidence? What if the snow didn’t carry on for just another 20km until I got out of the mountains, but I had to expect this for the next 200km?

It was one of those times when common sense and a desire to be safe and warm are pulling you back, and sheer stupid curiosity and determination are pulling you forward because if you don’t do this, you’ll never know what it’s like. I kept going.

Crawling along, I finally exited the mountains and arrived one town over for fuel and defrosting. Heavy snow gave way to light snow, then rain, and within an hour bright sunshine that filled the remainder of my trip towards San Martin de Los Andes.

That was a pretty awesome day!