diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b3f1861f452befc4e850601b706e8813c868fc99..7a39e594e6df9f0ee8335faa5cbb6c29d05a7efb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -38,6 +38,7 @@ win_installer:
    - git clone https://github.com/AllenDang/w32
    - cd w32
    - curl https://downloads.leap.se/thirdparty/w32.patch | patch -p1 -N
+
    - cd ${APP_PATH}
 
    - git clone https://0xacab.org/leap/riseup_vpn
diff --git a/standalone/bonafide.go b/standalone/bonafide.go
index e37c332bfa4ce200f1e9a8aecca668ce0e7e3fc0..e28eb089ab2cf4c19fce88120dc5a7217d5f0457 100644
--- a/standalone/bonafide.go
+++ b/standalone/bonafide.go
@@ -34,6 +34,7 @@ import (
 const (
 	certAPI        = "https://api.black.riseup.net/1/cert"
 	eipAPI         = "https://api.black.riseup.net/1/config/eip-service.json"
+	geolocationAPI = "https://api.black.riseup.net/getmyip/json"
 	secondsPerHour = 60 * 60
 )
 
@@ -78,6 +79,7 @@ type bonafide struct {
 	eip            *eipService
 	defaultGateway string
 }
+
 type httpClient interface {
 	Post(url, contentType string, body io.Reader) (resp *http.Response, err error)
 }
@@ -103,6 +105,20 @@ type gateway struct {
 	Location  string
 }
 
+type gatewayDistance struct {
+	gateway  gateway
+	distance int
+}
+
+type geoLocation struct {
+	IPAddress      string   `json:"ip"`
+	Country        string   `json:"cc"`
+	City           string   `json:"city"`
+	Latitude       float64  `json:"lat"`
+	Longitude      float64  `json:"lon"`
+	SortedGateways []string `json:"gateways"`
+}
+
 func newBonafide() *bonafide {
 	certs := x509.NewCertPool()
 	certs.AppendCertsFromPEM(caCert)
@@ -172,12 +188,34 @@ func (b *bonafide) getOpenvpnArgs() ([]string, error) {
 				args = append(args, "--"+arg)
 			}
 		default:
-			log.Printf("Uknwon openvpn argument type: %s - %v", arg, value)
+			log.Printf("Unknown openvpn argument type: %s - %v", arg, value)
 		}
 	}
 	return args, nil
 }
 
+func (b *bonafide) fetchGeolocation() ([]string, error) {
+	resp, err := b.client.Post(geolocationAPI, "", nil)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != 200 {
+		return nil, fmt.Errorf("get geolocation failed with status: %s", resp.Status)
+	}
+
+	geo := &geoLocation{}
+	dataJSON, err := ioutil.ReadAll(resp.Body)
+	err = json.Unmarshal(dataJSON, &geo)
+	if err != nil {
+		_ = fmt.Errorf("get vpn cert has failed with status: %s", resp.Status)
+		return nil, err
+	}
+
+	return geo.SortedGateways, nil
+
+}
+
 func (b *bonafide) fetchEipJSON() error {
 	resp, err := b.client.Post(eipAPI, "", nil)
 	if err != nil {
@@ -200,13 +238,22 @@ func (b *bonafide) fetchEipJSON() error {
 	return nil
 }
 
-func (b *bonafide) sortGateways() {
-	type gatewayDistance struct {
-		gateway  gateway
-		distance int
+func (b *bonafide) sortGatewaysByGeolocation(geolocatedGateways []string) []gatewayDistance {
+	gws := []gatewayDistance{}
+
+	for i, host := range geolocatedGateways {
+		for _, gw := range b.eip.Gateways {
+			if gw.Host == host {
+				gws = append(gws, gatewayDistance{gw, i})
+			}
+		}
 	}
+	return gws
+}
 
+func (b *bonafide) sortGatewaysByTimezone() []gatewayDistance {
 	gws := []gatewayDistance{}
+
 	for _, gw := range b.eip.Gateways {
 		distance := 13
 		if gw.Location == b.defaultGateway {
@@ -221,23 +268,29 @@ func (b *bonafide) sortGateways() {
 		}
 		gws = append(gws, gatewayDistance{gw, distance})
 	}
-
 	rand.Seed(time.Now().UnixNano())
 	cmp := func(i, j int) bool {
 		if gws[i].distance == gws[j].distance {
-			// TODO: a hack to distribute more the load into the new gw.
-			//       Let's delete it as soon as is more spread the load.
-			if gws[i].gateway.Host == "giraffe.riseup.net" {
-				return rand.Intn(4) != 0
-			} else if gws[j].gateway.Host == "giraffe.riseup.net" {
-				return rand.Intn(4) == 0
-			}
-
 			return rand.Intn(2) == 1
 		}
 		return gws[i].distance < gws[j].distance
 	}
 	sort.Slice(gws, cmp)
+	return gws
+}
+
+func (b *bonafide) sortGateways() {
+	gws := []gatewayDistance{}
+
+	geolocatedGateways, _ := b.fetchGeolocation()
+
+	if len(geolocatedGateways) > 0 {
+		gws = b.sortGatewaysByGeolocation(geolocatedGateways)
+	} else {
+		log.Printf("Falling back to timezone heuristic for gateway selection")
+		gws = b.sortGatewaysByTimezone()
+	}
+
 	for i, gw := range gws {
 		b.eip.Gateways[i] = gw.gateway
 	}