box-sizing:border-box
}
.WB18 *{
box-sizing:inherit
}
.WB18 a{
transition-property:background-color,color;
transition-duration:.2s
}
.grid>div{
float:left
}
.grid{
display:flex;
flex-direction:column
}
.font__display–proxima{
font-family:proxima-nova,”Helvetica Neue”,Helvetica,Arial,sans-serif
}
.font__display–jubilat{
font-family:jubilat,Georgia,serif
}
.WB18 h1,.WB18 h2,.WB18 h3,.WB18 h4,.WB18 h5,.WB18 h6{
font-family:proxima-nova,”Helvetica Neue”,Helvetica,Arial,sans-serif;
font-weight:900
}
.WB18__header–wrap{
/*margin-bottom:2em */
}
.WB18__header{
display:block;
padding: 0;
text-align:center;
background-color:#2fbcf2;
color:#fff;
background-position:center center;
font-family:jubilat,Georgia,serif;
cursor:pointer
}
.WB18__header:hover{
color:#afeeee;
background-color:#29c4f2
}
.WB18__header span{
display:inline-block;
color:#dc1b1b;
transition-property:color;
transition-duration:.2s
}
.WB18__header span.to-animate{
animation-name:tada;
animation-duration:.9s;
animation-delay:1s
}
.WB18__header:hover span{
color:#dc143c
}
.WB18__header:hover span.label__year{
color:#444
}
.WB18__desktop {
display: none;
}
@media (min-width:768px){
.grid{
flex-direction:row
}
.grid>*{
padding-left:1em;
padding-right:1em;
flex-grow:1
}
.grid>:first-child{
margin-left:0
}
.grid>:last-child{
margin-right:0
}
.block{
width:100%
}
.WB18__header{
padding:0;
}
}
.WB18__headline,.single-post article h1.WB18__headline{
color:#fff
}
.WB18__header .label__year{
display:block;
position:absolute;
line-height:1em;
padding:.3em .8em .2em;
top:.25em;
right:.25em;
background-color:gold;
color:#444;
font-weight:900;
box-shadow:2px 2px 6px rgba(0,0,0,.5);
border-radius:20%/50%
}
.WB18__nav{
display:flex;
flex-wrap:wrap;
flex-direction:column;
margin:0;
background-color:#eee
}
@media (min-width:768px){
.WB18__header .label__year{
font-size:1.4em;
right:-.25em
}
.WB18__nav{
flex-direction:row;
justify-content:stretch
}
.WB18__nav a,.WB18__nav button{
/* flex-grow:1 */
flex-basis: 50%;
}
}
@media (min-width: 1264px){
.WB18__nav a,.WB18__nav button{
/* flex-grow:1 */
flex-basis: 25%;
}
}
.WB18__nav a,.WB18__nav button{
padding:1rem 0.8rem;
border:0;
text-align:left;
background-color:#eee;
color:#dc1b1b;
font-family:proxima-nova,”Helvetica Neue”,Helvetica,Arial,sans-serif
}
#WB18__nav–togglerOne.active,#WB18__nav–togglerTwo.active,.WB18__nav a:hover,.WB18__nav button:hover{
background-color:#29c4f2;
color:#fff
}
.WB18__nav–overview{
order:1
}
.WB18__nav–other{
order:2
}
#WB18__nav–togglerOne{
order:3
}
#WB18__nav–togglerTwo{
order:4
}
.WB18__nav button{
outline:0
}
.WB18__nav #WB18__nav–togglerOne,.WB18__nav #WB18__nav–togglerTwo{
position:relative;
z-index:20
}
.WB18__nav #WB18__nav–togglerOne::after,.WB18__nav #WB18__nav–togglerTwo::after{
display:inline-block;
padding:0 1rem;
content:’ 025BE’;
transition-property:transform;
transition-duration:.2s
}
.WB18__nav #WB18__nav–togglerOne.active::after,.WB18__nav #WB18__nav–togglerTwo.active::after{
content:’ 025BE’;
transform:rotate(180deg)
}
.WB18__nav–citylistOne,.WB18__nav–citylistTwo{
position:absolute;
display:flex;
width:100%;
z-index:10;
flex-direction:column;
transform:translateX(-999em);
box-shadow:0 6px 4px rgba(0,0,0,.5)
}
.WB18__nav–citylistOne.active,.WB18__nav–citylistTwo.active{
transform:translateX(0);
z-index:20
}
.WB18__nav–citylistOne a,.WB18__nav–citylistTwo a{
background-color:#29c4f2;
color:#eee
}
.WB18__nav–citylistOne a:hover,.WB18__nav–citylistTwo a:hover{
background-color:#444;
color:#eee
}
@media (min-width:768px){
.WB18__nav–overview{
order:1
}
.WB18__nav–other{
order:4
}
#WB18__nav–togglerOne{
order:2
}
#WB18__nav–togglerTwo{
order:3
}
.WB18__mobile {
display: none;
}
.WB18__desktop {
display: block;
}
}
@keyframes tada{
from,to{
–transform:scale3d(1,1,1);
transform:scale3d(1,1,1)
}
10%,20%{
–transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);
transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)
}
30%,50%,70%,90%{
–transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);
transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)
}
40%,60%,80%{
–transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);
transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)
}
}
! function(e, t) { “object” == typeof exports && “object” == typeof module ? module.exports = t() : “function” == typeof define && define.amd ? define([], t) : “object” == typeof exports ? exports.inView = t() : e.inView = t() }(this, function() { return function(e) { function t(i) { if (n[i]) return n[i].exports; var r = n[i] = { exports: {}, id: i, loaded: !1 }; return e[i].call(r.exports, r, r.exports, t), r.loaded = !0, r.exports } var n = {}; return t.m = e, t.c = n, t.p = “”, t(0) }([function(e, t, n) { “use strict”; var i, r = n(2), o = (i = r) && i.__esModule ? i : { default: i }; e.exports = o.default }, function(e, t) { e.exports = function(e) { var t = typeof e; return null != e && (“object” == t || “function” == t) } }, function(e, t, n) { “use strict”; function i(e) { return e && e.__esModule ? e : { default: e } } Object.defineProperty(t, “__esModule”, { value: !0 }); var r = i(n(9)), o = i(n(3)), u = n(4); t.default = function() { if (“undefined” != typeof window) { var e = { history: [] }, t = { offset: {}, threshold: 0, test: u.inViewport }, n = (0, r.default)(function() { e.history.forEach(function(t) { e[t].check() }) }, 100); [“scroll”, “resize”, “load”].forEach(function(e) { return addEventListener(e, n) }), window.MutationObserver && addEventListener(“DOMContentLoaded”, function() { new MutationObserver(n).observe(document.body, { attributes: !0, childList: !0, subtree: !0 }) }); var i = function(n) { if (“string” == typeof n) { var i = [].slice.call(document.querySelectorAll(n)); return e.history.indexOf(n) > -1 ? e[n].elements = i : (e[n] = (0, o.default)(i, t), e.history.push(n)), e[n] } }; return i.offset = function(e) { if (void 0 === e) return t.offset; var n = function(e) { return “number” == typeof e }; return [“top”, “right”, “bottom”, “left”].forEach(n(e) ? function(n) { return t.offset[n] = e } : function(i) { return n(e[i]) ? t.offset[i] = e[i] : null }), t.offset }, i.threshold = function(e) { return “number” == typeof e && e >= 0 && e <= 1 ? t.threshold = e : t.threshold }, i.test = function(e) { return "function" == typeof e ? t.test = e : t.test }, i.is = function(e) { return t.test(e, t) }, i.offset(0), i } }() }, function(e, t) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); var n = function() { function e(e, t) { for (var n = 0; n -1, o = !n && r; n && !r && (e.current.push(t), e.emit(“enter”, t)), o && (e.current.splice(i, 1), e.emit(“exit”, t)) }), this } }, { key: “on”, value: function(e, t) { return this.handlers[e].push(t), this } }, { key: “once”, value: function(e, t) { return this.singles[e].unshift(t), this } }, { key: “emit”, value: function(e, t) { for (; this.singles[e].length;) this.singles[e].pop()(t); for (var n = this.handlers[e].length; –n > -1;) this.handlers[e][n](t); return this } }]), e }(); t.default = function(e, t) { return new i(e, t) } }, function(e, t) { “use strict”; Object.defineProperty(t, “__esModule”, { value: !0 }), t.inViewport = function(e, t) { var n = e.getBoundingClientRect(), i = n.top, r = n.right, o = n.bottom, u = n.left, c = n.width, s = n.height, f = o, a = window.innerWidth – u, l = window.innerHeight – i, d = r, p = t.threshold * c, h = t.threshold * s; return f > t.offset.top + h && a > t.offset.right + p && l > t.offset.bottom + h && d > t.offset.left + p } }, function(e, t) { (function(t) { var n = “object” == typeof t && t && t.Object === Object && t; e.exports = n }).call(t, function() { return this }()) }, function(e, t, n) { var i = n(5), r = “object” == typeof self && self && self.Object === Object && self, o = i || r || Function(“return this”)(); e.exports = o }, function(e, t, n) { var i = n(1), r = n(8), o = n(10), u = “Expected a function”, c = Math.max, s = Math.min; e.exports = function(e, t, n) { function f(t) { var n = h, i = v; return h = v = void 0, w = t, m = e.apply(i, n) } function a(e) { var n = e – b; return void 0 === b || n >= t || n = y } function l() { var e, n, i = r(); return a(i) ? d(i) : void(g = setTimeout(l, (e = i, n = t – (e – b), x ? s(n, y – (e – w)) : n))) } function d(e) { return g = void 0, T && h ? f(e) : (h = v = void 0, m) } function p() { var e, n = r(), i = a(n); if (h = arguments, v = this, b = n, i) { if (void 0 === g) return e = b, w = e, g = setTimeout(l, t), O ? f(e) : m; if (x) return g = setTimeout(l, t), f(b) } return void 0 === g && (g = setTimeout(l, t)), m } var h, v, y, m, g, b, w = 0, O = !1, x = !1, T = !0; if (“function” != typeof e) throw new TypeError(u); return t = o(t) || 0, i(n) && (O = !!n.leading, y = (x = “maxWait” in n) ? c(o(n.maxWait) || 0, t) : y, T = “trailing” in n ? !!n.trailing : T), p.cancel = function() { void 0 !== g && clearTimeout(g), w = 0, h = b = v = g = void 0 }, p.flush = function() { return void 0 === g ? m : d(r()) }, p } }, function(e, t, n) { var i = n(6); e.exports = function() { return i.Date.now() } }, function(e, t, n) { var i = n(7), r = n(1), o = “Expected a function”; e.exports = function(e, t, n) { var u = !0, c = !0; if (“function” != typeof e) throw new TypeError(o); return r(n) && (u = “leading” in n ? !!n.leading : u, c = “trailing” in n ? !!n.trailing : c), i(e, t, { leading: u, maxWait: t, trailing: c }) } }, function(e, t) { e.exports = function(e) { return e } }]) }), function(e, t) { if (“function” == typeof define && define.amd) define([“module”, “exports”], t); else if (“undefined” != typeof exports) t(module, exports); else { var n = { exports: {} }; t(n, n.exports), e.fitty = n.exports } }(this, function(e, t) { “use strict”; Object.defineProperty(t, “__esModule”, { value: !0 }); var n = Object.assign || function(e) { for (var t = 1; t 1 && void 0 !== arguments[1] ? arguments[1] : {}; return “string” == typeof e ? t(r(document.querySelectorAll(e)), n) : t([e], n)[0] } if (e) { var r = function(e) { return [].slice.call(e) }, o = { IDLE: 0, DIRTY_CONTENT: 1, DIRTY_LAYOUT: 2, DIRTY: 3 }, u = [], c = null, s = “requestAnimationFrame” in e ? function() { e.cancelAnimationFrame(c), c = e.requestAnimationFrame(function() { a(u.filter(function(e) { return e.dirty })) }) } : function() {}, f = function(e) { return function() { u.forEach(function(t) { t.dirty = e }), s() } }, a = function(e) { e.filter(function(e) { return !e.styleComputed }).forEach(function(e) { e.styleComputed = p(e) }), e.filter(h).forEach(y), e.filter(d).forEach(l), e.forEach(v), e.forEach(m) }, l = function(e) { e.availableWidth = e.element.parentNode.clientWidth, e.currentWidth = e.element.scrollWidth, e.previousFontSize = e.currentFontSize, e.currentFontSize = Math.min(Math.max(e.minSize, e.availableWidth / e.currentWidth * e.previousFontSize), e.maxSize), e.whiteSpace = e.multiLine && e.currentFontSize === e.minSize ? “normal” : “nowrap” }, d = function(e) { return e.dirty !== o.DIRTY_LAYOUT || e.dirty === o.DIRTY_LAYOUT && e.element.parentNode.clientWidth !== e.availableWidth }, p = function(t) { var n = e.getComputedStyle(t.element, null); t.currentFontSize = parseInt(n.getPropertyValue(“font-size”), 10), t.display = n.getPropertyValue(“display”), t.whiteSpace = n.getPropertyValue(“white-space”) }, h = function(e) { var t = !1; return /inline-/.test(e.display) || (t = !0, e.display = “inline-block”), “nowrap” !== e.whiteSpace && (t = !0, e.whiteSpace = “nowrap”), t }, v = function(e) { y(e), e.dirty = o.IDLE }, y = function(e) { e.originalStyle || (e.originalStyle = e.element.getAttribute(“style”) || “”), e.element.style.cssText = e.originalStyle + “;white-space:” + e.whiteSpace + “;display:” + e.display + “;font-size:” + e.currentFontSize + “px” }, m = function(e) { e.element.dispatchEvent(new CustomEvent(“fit”, { detail: { oldValue: e.previousFontSize, newValue: e.currentFontSize, scaleFactor: e.currentFontSize / e.previousFontSize } })) }, g = function(e, t) { return function() { e.dirty = t, s() } }, b = function(e) { e.newbie = !0, e.dirty = !0, u.push(e) }, w = function(e) { return function() { u = u.filter(function(t) { return t.element !== e.element }), e.observeMutations && e.observer.disconnect(), e.element.style.cssText = e.originalStyle } }, O = function(e) { e.observeMutations && (e.observer = new MutationObserver(g(e, o.DIRTY_CONTENT)), e.observer.observe(e.element, e.observeMutations)) }, x = { minSize: 16, maxSize: 512, multiLine: !0, observeMutations: “MutationObserver” in e && { subtree: !0, childList: !0, characterData: !0 } }, T = null, L = function() { e.clearTimeout(T), T = e.setTimeout(f(o.DIRTY_LAYOUT), i.observeWindowDelay) }, S = [“resize”, “orientationchange”]; return Object.defineProperty(i, “observeWindow”, { set: function(t) { var n = (t ? “add” : “remove”) + “EventListener”; S.forEach(function(t) { e[n](t, L) }) } }), i.observeWindow = !0, i.observeWindowDelay = 100, i.fitAll = f(o.DIRTY), i } }(“undefined” == typeof window ? null : window), e.exports = t.default }), fitty(“.fit”), inView(“.fit”).on(“enter”, function() { fitty(“.fit”) }), function(e) { function t() { if (this.id === “WB18__nav–togglerOne”) { !1 === e.cityListOneOpen ? e.cityListOneOpen = !0 : e.cityListOneOpen = !1, e.togglerOne.classList.toggle(“active”), e.submenuOne.classList.toggle(“active”); } else if (this.id === “WB18__nav–togglerTwo”) { !1 === e.cityListTwoOpen ? e.cityListTwoOpen = !0 : e.cityListTwoOpen = !1, e.togglerTwo.classList.toggle(“active”), e.submenuTwo.classList.toggle(“active”); } } e.cityListOneOpen = !1, e.togglerOne = document.querySelector(“#WB18__nav–togglerOne”), e.submenuOne = document.querySelector(“.WB18__nav–citylistOne”), e.togglerOne.addEventListener(“click”, t), e.addEventListener(“keyup”, function(n) { 27 === n.keyCode && !0 === e.cityListOneOpen && t() }), e.cityListTwoOpen = !1, e.togglerTwo = document.querySelector(“#WB18__nav–togglerTwo”), e.submenuTwo = document.querySelector(“.WB18__nav–citylistTwo”), e.togglerTwo.addEventListener(“click”, t), e.addEventListener(“keyup”, function(n) { 27 === n.keyCode && !0 === e.cityListTwoOpen && t() }) }(this);

Cochrane, Alberta looking west from the Glen Eagles subdivision (Chuck Szmurlo/Wikimedia Commons)
Some people consider life in a fast-growing city to be a plague of inconveniences and expenses, but many places would love to have those problems.
New residents bring congestion and rising housing prices, but they also provide economic stimulus, tax revenues and families that become part of the community’s fabric. The change may seem annoying to long-time residents, but the newcomers obviously chose the city for a reason.
As far as we’re concerned, growth is good, and we updated the Best Places to Live methodology to reflect that. Previously, cities were penalized if their five-year growth rates were too far above the national average; now, the faster a city is growing, the more points it gets.
Particularly fast growth rates in a suburb might simply signal the construction of a lot of new housing, especially since most cities are part of larger urban metro areas. Those new dwellings attract a disproportionate number of new residents to the region if housing elsewhere is unaffordable or unavailable.
PHOTOS:
Take Cochrane, Alta., the fastest-growing city in the country. With an annualized five-year growth rate of 5.6 per cent, it’s adding residents at more than double the rate of Calgary, a 30-minute drive west, thanks to thousands of new housing units added over the past eight years.
Are some cities dealing with growth better than others? Almost certainly. But if that’s the case, we believe it will be reflected in other categories in the ranking.
The five-year population growth is the only component of the demographics category in the main ranking, worth six per cent of the total. Cities with zero or negative five-year population growth received zero points. For more information, please see the methodology page.
The Top 100
th {
vertical-align: bottom;
text-align: left;
}
.table-holder {
display: block;
overflow-x: scroll;
width: 100%;
}
Search to filter by city or province:
Rank | City | Province | Population | Annualized five-year growth rate |
---|---|---|---|---|
1 | Cochrane | AB | 28,789 | 5.6% |
2 | Airdrie | AB | 69,164 | 5.4% |
3 | Chestermere | AB | 21,911 | 4.4% |
4 | Spruce Grove | AB | 37,654 | 4.2% |
5 | Milton | ON | 120,556 | 4.1% |
6 | Beaumont | AB | 19,068 | 4.1% |
7 | Fort Saskatchewan | AB | 26,718 | 3.9% |
8 | Mirabel | QC | 55,575 | 3.8% |
9 | Saint-Colomban | QC | 17,225 | 3.5% |
10 | Leduc | AB | 32,921 | 3.5% |
11 | King | ON | 26,697 | 3.4% |
12 | Bradford West Gwillimbury | ON | 37,754 | 3.4% |
13 | Saint-Lin–Laurentides | QC | 22,582 | 3.4% |
14 | Whitchurch-Stouffville | ON | 50,099 | 3.3% |
15 | Greater Vancouver | BC | 17,507 | 3.3% |
16 | Whistler | BC | 13,193 | 3.2% |
17 | Lloydminster | SK | 13,089 | 3.2% |
18 | Sainte-Sophie | QC | 16,953 | 3.1% |
19 | Paradise | NL | 23,067 | 3.0% |
20 | Steinbach | MB | 16,900 | 3.0% |
21 | Winkler | MB | 13,768 | 2.9% |
22 | Okotoks | AB | 31,613 | 2.9% |
23 | Sylvan Lake | AB | 16,052 | 2.8% |
24 | Langford | BC | 36,977 | 2.8% |
25 | Wasaga Beach | ON | 21,993 | 2.7% |
26 | Hanover | MB | 17,012 | 2.7% |
27 | Brampton | ON | 657,141 | 2.6% |
28 | Caledon | ON | 73,540 | 2.6% |
29 | Edmonton | AB | 1,020,976 | 2.5% |
30 | Squamish | BC | 21,421 | 2.5% |
31 | Taché | MB | 12,357 | 2.5% |
32 | Bonnyville No. 87 | AB | 14,658 | 2.5% |
33 | Stony Plain | AB | 18,640 | 2.4% |
34 | Vaudreuil-Dorion | QC | 40,303 | 2.4% |
35 | New Tecumseth | ON | 36,745 | 2.3% |
36 | Sainte-Marthe-sur-le-Lac | QC | 19,064 | 2.3% |
37 | Calgary | AB | 1,359,777 | 2.3% |
38 | Saskatoon | SK | 274,104 | 2.2% |
39 | Collingwood | ON | 23,190 | 2.2% |
40 | Langley | BC | 125,264 | 2.2% |
41 | Grande Prairie | AB | 69,175 | 2.1% |
42 | Essa | ON | 22,417 | 2.1% |
43 | Mercier | QC | 14,101 | 2.1% |
44 | Chambly | QC | 30,320 | 2.1% |
45 | Rocky View County | AB | 42,788 | 2.0% |
46 | Innisfil | ON | 38,942 | 2.0% |
47 | Grande Prairie County No. 1 | AB | 24,037 | 2.0% |
48 | Saint-Amable | QC | 12,797 | 2.0% |
49 | Val-des-Monts | QC | 12,224 | 2.0% |
50 | Sooke | BC | 13,446 | 2.0% |
51 | Markham | ON | 358,416 | 2.0% |
52 | Lake Country | BC | 13,582 | 2.0% |
53 | Regina | SK | 232,654 | 2.0% |
54 | Surrey | BC | 552,455 | 1.9% |
55 | Lethbridge | AB | 99,165 | 1.9% |
56 | Mascouche | QC | 49,548 | 1.9% |
57 | Coquitlam | BC | 148,747 | 1.9% |
58 | Niagara-on-the-Lake | ON | 18,026 | 1.8% |
59 | Saint-Jérôme | QC | 78,756 | 1.8% |
60 | East Gwillimbury | ON | 26,202 | 1.8% |
61 | L’Assomption | QC | 23,346 | 1.8% |
62 | Lacombe | AB | 13,906 | 1.8% |
63 | Kelowna | BC | 134,234 | 1.7% |
64 | Dieppe | NB | 26,982 | 1.7% |
65 | Canmore | AB | 14,930 | 1.7% |
66 | North Vancouver | BC | 56,176 | 1.7% |
67 | Ajax | ON | 127,977 | 1.7% |
68 | Clarington | ON | 98,586 | 1.7% |
69 | Prévost | QC | 13,771 | 1.7% |
70 | Red Deer | AB | 107,564 | 1.7% |
71 | Foothills No. 31 | AB | 24,713 | 1.7% |
72 | Sainte-Adèle | QC | 13,744 | 1.6% |
73 | Saint-Constant | QC | 29,295 | 1.6% |
74 | Strathmore | AB | 14,490 | 1.6% |
75 | St. Albert | AB | 70,874 | 1.6% |
76 | Vaughan | ON | 332,250 | 1.6% |
77 | Cantley | QC | 11,219 | 1.6% |
78 | Maple Ridge | BC | 87,346 | 1.6% |
79 | Chilliwack | BC | 88,448 | 1.6% |
80 | Winnipeg | MB | 755,029 | 1.5% |
81 | Oakville | ON | 209,039 | 1.5% |
82 | Cowansville | QC | 14,109 | 1.5% |
83 | Severn | ON | 14,205 | 1.5% |
84 | Brossard | QC | 89,699 | 1.5% |
85 | Brandon | MB | 51,483 | 1.5% |
86 | Charlottetown | PEI | 39,437 | 1.5% |
87 | Strathcona County | AB | 105,899 | 1.5% |
88 | New Westminster | BC | 75,570 | 1.5% |
89 | Nanaimo | BC | 94,760 | 1.5% |
90 | Parkland County | AB | 34,679 | 1.4% |
91 | Mountain View County | AB | 14,150 | 1.4% |
92 | Richmond Hill | ON | 211,034 | 1.4% |
93 | Mission | BC | 40,977 | 1.4% |
94 | Newmarket | ON | 90,908 | 1.4% |
95 | Oshawa | ON | 170,445 | 1.4% |
96 | Georgina | ON | 49,318 | 1.4% |
97 | High River | AB | 14,726 | 1.4% |
98 | Thompson | MB | 14,697 | 1.4% |
99 | Abbotsford | BC | 149,466 | 1.4% |
100 | Esquimalt | BC | 18,273 | 1.4% |
jQuery(document).ready(function(){
jQuery(‘#a01c512505e8’).footable();
});
The post Top 100 Fastest-Growing Cities in Canada 2018 appeared first on MoneySense.