diff --git a/src/core/Core.cpp b/src/core/Core.cpp
index 8000752258142b5fd5831fae73dd5439bd1e2a54..64cd79a1b3f39f89e5a6327cd4b76dc599402f14 100644
--- a/src/core/Core.cpp
+++ b/src/core/Core.cpp
@@ -369,6 +369,7 @@ int Core::get_options(int &argc, char **argv)
  **********************************/
 
 bool Core::draw_trace(const string & filename, const int format) {
+    delete parser;
     parser = nullptr;
     DrawTrace  drawing_ogl;
     bool killed=false;
diff --git a/src/core/Core.hpp b/src/core/Core.hpp
index d5d57b109013546bf7bafde1433ed543155be420..c543adb7f3f46fce543145cd28044b3df7e2bf42 100644
--- a/src/core/Core.hpp
+++ b/src/core/Core.hpp
@@ -313,7 +313,7 @@ protected:
     Trace* _trace;
 
     QMutex*         _mutex;
-    Parser*         parser;
+    Parser*         parser = nullptr;
     QWaitCondition* _finished;
     QWaitCondition* _closed;
 
diff --git a/src/render/vbo/Render_alternate.cpp b/src/render/vbo/Render_alternate.cpp
index 32c296da83c28f4480a9cc3ac267b44651ea1c41..eb3d18ad7fa508eb7c238a8de9b9eb45b276bc21 100644
--- a/src/render/vbo/Render_alternate.cpp
+++ b/src/render/vbo/Render_alternate.cpp
@@ -146,6 +146,7 @@ Render_alternate::Render_alternate(Core* core, QWidget *parent, const QGLFormat&
 
 Render_alternate::~Render_alternate(){
     delete _wait;
+    delete _wait_shader;
     delete _shader;
 }
 
@@ -196,6 +197,7 @@ void  Render_alternate::initializeGL() {
     std::cout << "Version GLSL : " << version << std::endl;
     _glsl = (version[0]-'0')*100 + (version[2]-'0')*10 + version[3]-'0';
 
+    delete _shader;
     _shader = new Shader(_glsl);
     _shader->charger();
     draw_wait();
@@ -770,13 +772,34 @@ bool Render_alternate::unbuild(){
     _text_value.clear();
     clear_text();
     _links.clear();
+    for (auto& x : _states) delete x.second;
     _states.clear();
+    for (auto& x : _arrows) { delete x.second.first; delete x.second.second; }
     _arrows.clear();
+    for (auto& x : _events) { delete x.second.first; delete x.second.second; }
     _events.clear();
 
+    // >SHADER_POOL
+    // We need a shader pool here because VBO used to own heir shader so they used to delete it
+    // Then when we do "for (auto& x : _arrows) { delete x.second.first; delete x.second.second; }"
+    // we try to delete the same shader twice (second.first and second.second share the same shader)
+    // So we removed the shader from the hands of the VBO and we need to have a shader pool.
+
+    // Having a shader pool allows us to not manually allocate a shader for each VBO and to not
+    // fragment our memory. We need to use a special data structure that don't allocate a lot
+    // and that have stable pointer. For this we want an array of array basically a Bucket Array
+    // The implementation of this in the stl is std::deque, but... it's kind of bad we can't even
+    // specify the bucket sizes, we might want to implement it ourself.
+    _shader_pool.clear();
+
     return true;
 }
 
+template<typename... Args>
+Shader* new_shader(std::deque<Shader>& _shader_pool, Args&&... args) noexcept {
+    _shader_pool.emplace_back(std::forward<Args>(args)...);
+    return &_shader_pool.back();
+}
 
 
 
@@ -795,11 +818,11 @@ bool Render_alternate::unbuild(){
 
 GLuint Render_alternate::draw_wait() {
     if (_wait == nullptr) {
-        Shader *s = new Shader(_glsl, 0);
+        _wait_shader = new Shader(_glsl, 0);
 
         _wait = new Vbo();
-        s->charger();
-        _wait->set_shader(s);
+        _wait_shader->charger();
+        _wait->set_shader(_wait_shader);
 
         glGenTextures(1, &_textureID);
         glBindTexture(GL_TEXTURE_2D, _textureID);
@@ -962,7 +985,7 @@ void Render_alternate::start_draw(){
 
 void Render_alternate::start_draw_containers(){
     _draw_container = true;
-    Shader *s = new Shader(_glsl);
+    Shader *s = new_shader(_shader_pool, _glsl);
     s->charger();
     _containers.set_shader(s);
     _containers.setNbVertex(0);
@@ -994,7 +1017,7 @@ void Render_alternate::draw_state( const Element_pos x,
 {
     if( _states.count(value) == 0 ) { //if there is no vbo corresponding to value
         //we create a new vbo and a new shader corresponding to the current color*/
-        Shader *s = new Shader(_glsl, _r, _g, _b, true);
+        Shader *s = new_shader(_shader_pool, _glsl, _r, _g, _b, true);
         s->charger();
         //assert(value); // TODO: check why busy state exists and uncomment this assert
         Vbo *v = new Vbo(s);
@@ -1037,7 +1060,7 @@ void Render_alternate::draw_arrow( const Element_pos start_time,
 {
     if(_arrows.count(value) == 0){ //if there is no vbo corresponding to value
         /* Create a new vbo and a new shader*/
-        Shader *s = new Shader(_glsl, _r, _g, _b, false);
+        Shader *s = new_shader(_shader_pool, _glsl, _r, _g, _b, false);
         s->charger();
         Vbo* v1 = new Vbo(s);
         Vbo* v2 = new Vbo(s);
@@ -1108,7 +1131,7 @@ void Render_alternate::start_draw_events(){
 
 void Render_alternate::draw_event(const Element_pos time, const Element_pos height,  const Element_pos container_height, EntityValue* value){
     if(_events.count(value) == 0){
-        Shader *s = new Shader(_glsl, _r, _g, _b, false);
+        Shader *s = new_shader(_shader_pool, _glsl, _r, _g, _b, false);
         s->charger();
         Vbo* v1 = new Vbo(s);
         Vbo* v2 = new Vbo(s);
@@ -1144,7 +1167,7 @@ void Render_alternate::end_draw_events(){
 void Render_alternate::start_draw_counter(){
     _draw_counter = true;
     /* create shader for counters : all vertex are white */
-    Shader *s = new Shader(_glsl, 1, 1, 1, false);
+    Shader *s = new_shader(_shader_pool, _glsl, 1, 1, 1, false);
     s->charger();
     _counters.set_shader(s);
 }
@@ -1270,7 +1293,7 @@ Render_alternate::update_ev_single( EntityValue *ev,
         vbo->delete_shader();
 
         //create and load the new shader*/
-        Shader *s = new Shader(_glsl,
+        Shader *s = new_shader(_shader_pool, _glsl,
                                c->get_red(),
                                c->get_green(),
                                c->get_blue(),
@@ -1293,11 +1316,15 @@ Render_alternate::update_ev_couple( EntityValue *ev,
         Vbo   *vbo2 = it->second.second;
         Color *c = ev->get_used_color();
 
+        // >TODO
+        // Because now we have a shader pool we might just prefer to update the shader of vbo1 in
+        // in place. But i'm keeping this merge request short.
+
         //delete previous shader
         vbo1->delete_shader();
 
         //create and load the new shader*/
-        Shader *s = new Shader(_glsl,
+        Shader *s = new_shader(_shader_pool, _glsl,
                                c->get_red(),
                                c->get_green(),
                                c->get_blue(),
@@ -1348,7 +1375,7 @@ void Render_alternate::change_color(const std::string &entity,
             //delete previous shader
             it->second->delete_shader();
             //create and load the new shader*/
-            Shader *s = new Shader(_glsl, r, g, b, true);
+            Shader *s = new_shader(_shader_pool, _glsl, r, g, b, true);
             s->charger();
             it->second->set_shader(s);
             break;
@@ -1367,7 +1394,7 @@ void Render_alternate::change_event_color(const std::string &event, Element_col
             Color *c = new Color(r, g, b);
             it->first->set_used_color(c);
             it->second.first->delete_shader();
-            Shader *s = new Shader(_glsl, r, g, b, false);
+            Shader *s = new_shader(_shader_pool, _glsl, r, g, b, false);
             s->charger();
             it->second.first->set_shader(s);
             it->second.second->set_shader(s);
@@ -1387,7 +1414,7 @@ void Render_alternate::change_link_color(const std::string &link, Element_col r,
             Color *c = new Color(r, g, b);
             it->first->set_used_color(c);
             it->second.first->delete_shader();
-            Shader *s = new Shader(_glsl, r, g, b, false);
+            Shader *s = new_shader(_shader_pool, _glsl, r, g, b, false);
             s->charger();
             it->second.first->set_shader(s);
             it->second.second->set_shader(s);
@@ -1444,7 +1471,7 @@ void Render_alternate::reload_states(){
             it->first->reload_file_color();
             it->first->set_visible(true);
             it->second->delete_shader();
-            Shader* s = new Shader(_glsl, it->first->get_used_color()->get_red(),
+            Shader* s = new_shader(_shader_pool, _glsl, it->first->get_used_color()->get_red(),
                                    it->first->get_used_color()->get_green(),
                                    it->first->get_used_color()->get_blue(),
                                    true);
@@ -1461,7 +1488,7 @@ void Render_alternate::reload_links(){
             it->first->reload_file_color();
             it->first->set_visible(true);
             it->second.first->delete_shader();
-            Shader* s = new Shader(_glsl, it->first->get_used_color()->get_red(),
+            Shader* s = new_shader(_shader_pool, _glsl, it->first->get_used_color()->get_red(),
                                    it->first->get_used_color()->get_green(),
                                    it->first->get_used_color()->get_blue(),
                                    false);
@@ -1480,7 +1507,7 @@ void Render_alternate::reload_events(){
             it->first->reload_file_color();
             it->first->set_visible(true);
             it->second.first->delete_shader();
-            Shader* s = new Shader(_glsl, it->first->get_used_color()->get_red(),
+            Shader* s = new_shader(_shader_pool, _glsl, it->first->get_used_color()->get_red(),
                                    it->first->get_used_color()->get_green(),
                                    it->first->get_used_color()->get_blue(),
                                    false);
diff --git a/src/render/vbo/Render_alternate.hpp b/src/render/vbo/Render_alternate.hpp
index 06a5780c13ba62a4d5c9992a15134b67dd6fe25d..d533b58582f97a20f173a8d7b8718b1728ca32bb 100644
--- a/src/render/vbo/Render_alternate.hpp
+++ b/src/render/vbo/Render_alternate.hpp
@@ -49,6 +49,7 @@
 
 #include <stack>
 #include <cmath>
+#include <deque>
 #include <sstream>
 /* -- */
 #include <QObject>
@@ -110,7 +111,13 @@ private:
     //FT_Face face;
     //int atlas_width;
     int _glsl; //version of OpenGL Shading Language
-    Shader* _shader;
+    Shader* _shader = nullptr;
+    Shader* _wait_shader = nullptr;
+
+    // Here we are sad that we can't specify the bucket size :(.
+    // We might want to implement the Bucket Array data structure ourself.
+    // see >SHADER_POOL
+    std::deque<Shader> _shader_pool;
     //Shader* _wait_shader;
     Element_pos _container_height;
     Element_col _r;
diff --git a/src/render/vbo/vbo.cpp b/src/render/vbo/vbo.cpp
index f16efcba3f91f5c971cb3f5881677abfd6711ea6..34c3cb605e3400c19cac0dd5786239ef43d37f0b 100644
--- a/src/render/vbo/vbo.cpp
+++ b/src/render/vbo/vbo.cpp
@@ -88,7 +88,8 @@ Vbo::~Vbo(){
     _vboID = 0;
     glDeleteVertexArrays(1, &_vaoID);
     _vaoID = 0;
-    delete _shader;
+    // see >SHADER_POOL
+    // delete _shader;
 }
 
 
@@ -283,7 +284,8 @@ Shader * Vbo::get_shader(){
 
 void Vbo::delete_shader(){
     if (_shader != nullptr) {
-        delete _shader;
+        // see >SHADER_POOL
+        // delete _shader;
     }
     _shader = nullptr;
 }
@@ -292,7 +294,8 @@ void Vbo::delete_shader(){
  if precedent is not used anymore, delete_shader should be called before this function*/
 void Vbo::set_shader(Shader *s){
     if ( _shader != nullptr ) {
-        delete _shader;
+        // see >SHADER_POOL
+        // delete _shader;
     }
     _shader = s;
 }
diff --git a/src/trace/DrawTrace.hpp b/src/trace/DrawTrace.hpp
index 69c80da398318385f7ed57584e6ddb9898c0cbf5..37376358c96f1f74819f7b82f6bbd3838a1cb717 100644
--- a/src/trace/DrawTrace.hpp
+++ b/src/trace/DrawTrace.hpp
@@ -199,11 +199,14 @@ public:
         _link_containers.clear();
         _variable_containers.clear();
 
+        thread_local std::vector<const Container*> local_container;
+        local_container.clear();
         std::vector<const Container *> *container = trace->get_selected_container();
         if( (container == nullptr) ||
             container->empty() )
         {
-            container = new std::vector<const Container *>();
+            if (!container) container = &local_container;
+            container->clear();
 
             trace->set_filter(0);